| Tested on | RHEL 10.2 (Coughlan) |
|---|---|
| Package | iproute 6.17.0-2.el10firewalld 2.4.3-2.el10_2curl 8.12.1 |
| Applies to | Ubuntu, Debian, Kali Linux, Linux Mint, Pop!_OS, Raspberry Pi OS, elementary OS, Zorin OS, Parrot OS, MX Linux, RHEL, Rocky Linux, AlmaLinux, Oracle Linux, CentOS Stream, Fedora, Arch Linux |
| Privilege | Normal user on the client for diagnostics; sudo or root on the server for firewall and service changes (often through console when SSH is blocked) |
| Scope | Diagnose no route to host for any TCP client — ssh, curl, custom ports — using ip route get, neighbor tables, tracepath, and firewall REJECT inspection. Does not replace SSH-only sshd and ListenAddress checks covered in the dedicated SSH troubleshooting guide. |
| Related guides | Fix SSH no route to host Network is unreachable Test port connectivity firewalld cheat sheet traceroute command |
curl https://192.168.56.116 dies with Failed to connect … No route to host while ping 192.168.56.116 still gets replies. That combination usually means the kernel found a route to the IP, but something on the path — often a firewall REJECT on the TCP port — answered with ICMP host unreachable.
Work from the client: confirm the route exists, test the exact TCP port, check neighbors on the same subnet, then inspect REJECT rules on the server.
What no route to host means
Linux maps EHOSTUNREACH to the phrase no route to host on connect(). The name sounds like a missing static route, but the errno also covers:
- ICMP host unreachable or host prohibited from a router or firewall
- Neighbor (ARP) resolution failure on a directly connected subnet
- Local policy routing edge cases where the chosen path cannot forward
| Tool | Typical message |
|---|---|
ssh |
connect to host … port 22: No route to host |
curl |
Failed to connect … No route to host (curl error 7) |
bash /dev/tcp/… |
connect: No route to host |
nc |
Ncat: No route to host |
ping |
Usually different wording (Destination Host Unreachable after ARP timeout) |
Use an IP address first so DNS stays out of the picture. If only hostnames fail, see temporary failure in name resolution.
ip route get prints Network is unreachable with no via line, fix local routes and the default gateway first — that is ENETUNREACH, covered in network is unreachable. This guide assumes a route to the destination IP already exists.
Check the route to the destination
Ask the kernel which interface and source address it would use for the target:
ip route get 192.168.56.116192.168.56.116 dev eth0 src 192.168.56.156 uid 0
cacheThe dev line is the interface packets leave from; src is the source address peers and firewalls see. If this points at the wrong NIC after a VPN connect, fix local policy routing before changing the remote server.
For destinations outside local subnets, confirm a default gateway exists:
ip route show defaultdefault via 192.168.56.116 dev eth0 proto static metric 100When ip route get itself answers RTNETLINK answers: Network is unreachable, stop here and fix routing — the no route to host errors on applications are a consequence of that missing path.
Check gateway reachability
If traffic must leave through a gateway, ping the gateway IP from the same client:
ping -c2 -W2 192.168.56.116PING 192.168.56.116 (192.168.56.116) 56(84) bytes of data.
64 bytes from 192.168.56.116: icmp_seq=1 ttl=64 time=1.36 ms
64 bytes from 192.168.56.116: icmp_seq=2 ttl=64 time=1.18 ms
--- 192.168.56.116 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001msReplies mean L3 reachability to that IP works. That does not prove every TCP port is open — firewalls filter by protocol and port.
When the gateway does not answer ping, check link state on the client (ip -br link), cable or VLAN membership, and whether the gateway IP is correct for the subnet mask on that interface.
Check ARP and neighbor resolution
On the same broadcast domain, the kernel must resolve the destination MAC address before TCP can flow. Inspect the neighbor cache:
ip neigh show 192.168.56.116Healthy entry:
192.168.56.116 dev eth0 lladdr 08:00:27:c4:4f:20 REACHABLEREACHABLE means ARP succeeded recently. FAILED or INCOMPLETE on a host that should be up points at L2 problems — wrong VLAN, host powered off, duplicate IP, or a switch port issue — and can produce unreachable errors even when ip route get looks fine.
Clear a stale entry only when you suspect a bad MAC was cached, then retry:
sudo ip neigh del 192.168.56.116 dev eth0The next packet triggers a fresh ARP request.
Trace where connectivity stops
On a one-hop LAN, tracepath confirms the target responds at L3:
tracepath -n 192.168.56.1161: 192.168.56.116 0.111ms reached
Resume: pmtu 65535 hops 1 back 1reached on the first hop matches a directly connected host. For multi-hop paths, use traceroute or mtr to see which router returns ICMP unreachable.
TCP failures need a port-level test. Bash can open a socket without extra packages:
timeout 3 bash -c '</dev/tcp/192.168.56.116/443' && echo open || echo failedWhen a server firewall REJECTs the client with icmp-host-prohibited, the shell prints:
bash: connect: No route to host
bash: line 1: /dev/tcp/192.168.56.116/443: No route to host
failedThe same target with curl command shows the errno in the verbose log:
curl -v --max-time 3 http://192.168.56.116:443* connect to 192.168.56.116 port 443 from 192.168.56.156 port 45228 failed: No route to host
* Failed to connect to 192.168.56.116 port 443 after 2 ms: Could not connect to server
curl: (7) Failed to connect to 192.168.56.116 port 443 after 2 ms: Could not connect to serverNote the client source port line — firewall rules often match source IP, not only destination.
Check firewall REJECT rules
On RHEL-family systems, firewalld can REJECT blocked TCP with ICMP unreachable responses. The client then reports no route to host even though ping and ip route get succeed.
On the server, list the active zone:
sudo firewall-cmd --list-allLook under services, ports, and rich rules for what is allowed. Rich rules that REJECT a client source are easy to miss:
rich rules:
rule family="ipv4" source address="192.168.56.156" port port="443" protocol="tcp" reject type="icmp-host-prohibited"That pattern blocks HTTPS from one client IP while SSH from the same host may still work on port 22.
Allow the service permanently on the server zone:
sudo firewall-cmd --permanent --add-service=httpsReload firewalld so the rule is active:
sudo firewall-cmd --reloadOr remove a mistaken REJECT rule:
sudo firewall-cmd --permanent --remove-rich-rule='rule family="ipv4" source address="192.168.56.156" port port="443" protocol="tcp" reject type="icmp-host-prohibited"'Apply the removal:
sudo firewall-cmd --reloadOn any distro, search nftables or iptables for REJECT targets:
sudo nft list ruleset | grep -i rejectreject-with icmp host-prohibited and icmp-host-unreachable commonly map to no route to host on the client. DROP rules tend to cause timeouts instead.
Ports not allowed in the zone may be rejected before traffic reaches the application. Opening the port in the firewall is not the same as running a service — compare with connection refused below.
Verify the fix
Re-run the same TCP check that failed:
timeout 3 bash -c '</dev/tcp/192.168.56.116/443' && echo open || echo failedAfter the REJECT rule was removed and HTTPS allowed, the socket opens when a listener is present, or fails with connection refused when the port is open at the firewall but nothing listens.
Confirm neighbors and routing are still healthy:
ip neigh show 192.168.56.116192.168.56.116 dev eth0 lladdr 08:00:27:c4:4f:20 REACHABLEThe routing decision should still name the same outbound interface:
ip route get 192.168.56.116192.168.56.116 dev eth0 src 192.168.56.156 uid 0
cacheFor SSH-specific verification (sshd, ListenAddress, keys), continue with Fix SSH no route to host once TCP port 22 connects.
No route to host vs connection refused
Both errors appear before application data flows, but the fix differs:
| Message | errno | Route in ip route get |
Typical cause |
|---|---|---|---|
| No route to host | EHOSTUNREACH |
Often shows dev / via |
Firewall REJECT with ICMP unreachable, ARP failure, upstream ICMP |
| Connection refused | ECONNREFUSED |
Shows dev / via |
Port allowed through firewall but no listener, or TCP RST from host |
| Network is unreachable | ENETUNREACH |
Fails with RTNETLINK | Missing default route or no matching prefix |
| Connection timed out | — | May show route | Silent DROP along path |
Demonstration on the same server IP: with the firewall allowing port 59999 but no process listening, the client sees refused:
timeout 3 bash -c '</dev/tcp/192.168.56.116/59999' 2>&1bash: connect: Connection refused
bash: line 1: /dev/tcp/192.168.56.116/59999: Connection refusedWith the port blocked by REJECT instead, the same client IP gets no route to host on port 443 — fix the firewall rule, not the application daemon.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| Ping OK; TCP fails with no route to host | firewalld / nftables REJECT on that port or source IP |
Allow service/port; remove REJECT rich rules |
ip route get OK; TCP fails |
Same as above, or ARP FAILED |
ip neigh show; fix L2/VLAN; adjust firewall |
ip route get → Network is unreachable |
No route to destination network | Fix default gateway / routes |
| Works from some clients only | Source-based zone or rich rule | Compare client src from ip route get with firewall-cmd --list-rich-rules |
nc / curl timeout (not no route) |
DROP rule or dead path mid-network | tracepath / traceroute; check intermediate filters |
| SSH no route to host after OS hardening | SSH service dropped from zone | firewall-cmd --add-service=ssh; see SSH guide for sshd |
| After VPN connect | Traffic exits wrong interface | Policy routing / split tunnel; fix ip route get source |
References
- ip-route(8) — routing table and
ip route get - ip-neighbour(8) — ARP and neighbor cache
- firewalld.richlanguage(5) — REJECT types including
icmp-host-prohibited - errno(3) —
EHOSTUNREACHandECONNREFUSED - RFC 792 — ICMP — destination unreachable messages
Summary
No route to host is an EHOSTUNREACH error at the socket layer. It does not always mean your routing table is empty — on many Linux servers the message appears when a firewall REJECTs TCP with ICMP host prohibited while ICMP echo still passes.
Start with ip route get and a port-specific test (bash /dev/tcp, nc, or curl -v). If the route looks correct and ping works, read ip neigh for ARP problems, then inspect firewalld rich rules or nftables REJECT entries that match your client source IP and destination port.
Connection refused on the same IP means the packet reached the host and nothing accepted the socket — open the service or fix the listener. Network is unreachable means the kernel never found a route — fix gateways first. Once TCP connects for SSH, hand off to Fix SSH no route to host for sshd and authentication checks.

