Diagnosing "No route to host"
What Does "No route to host" Mean?
Conclusion: There is no usable path to deliver packets to the host. The kernel — or a device along the way — decided the destination is unreachable, and
EHOSTUNREACHis returned. Like refused, it fails immediately.
No route to host appears when something on the path to the destination decides it cannot deliver the packet. At the system-call level, connect() returns EHOSTUNREACH, which apps surface as "No route to host".
$ ssh user@192.0.2.10 ssh: connect to host 192.0.2.10 port 22: No route to host
$ curl http://192.0.2.10/ curl: (7) Failed to connect to 192.0.2.10 port 80 after 2 ms: No route to host
The verdict can come from three places: ① the local kernel decides there is no route at all, ② a host on the same segment does not answer ARP, or ③ a router or firewall along the path returns an ICMP host-unreachable / host-prohibited. In every case the reply comes back in a few milliseconds, which makes its behavior very different from a silent timeout.
Prerequisites
- OS: Ubuntu / a typical Linux (
ipcommand = iproute2) - Target: any host you want to reach by IP
- We assume you can read the routing and ARP tables without
sudo
How Is It Different from refused and timeout?
Conclusion: Refused means "arrived but rejected at the port", timeout means "no answer at all", and No route to host means "there is no path to deliver to it / the host cannot be reached". Same failed connection, completely different starting point.
Connection errors fall into three families that fail at different layers. Settle which one you have first.
| Error | What comes back | Layer of the cause |
|---|---|---|
| Connection refused | TCP RST (instant) | Service / port (L4, application) |
| Connection timed out | No response (long wait) | DROP / silent path (L3–L4) |
| No route to host | ICMP unreachable (instant) | Route / ARP / REJECT (L2–L3) |
$ time curl -sS http://192.0.2.10/
curl: (7) Failed to connect to 192.0.2.10 port 80 after 2 ms: No route to host real 0m0.012s
If No route to host returns in 0.0xx seconds, you are stopped before the destination host, somewhere on the path. For a stopped service or closed port see Connection refused; for a long silent wait see Port Connectivity. This article covers No route to host.
Refused is "the host is alive but the port turned me away"; No route to host is "there is no road to the host / it cannot be reached". The difference is decisive: this is an L2–L3 problem (path and reachability), not an L4 (port) problem.
Why Does "No route to host" Happen?
Conclusion: The cause reduces to four things — ① a missing local route, ② a failed ARP resolution on the same segment, ③ a router along the path rejecting with ICMP, or ④ a firewall's icmp-host-prohibited REJECT. Work from the nearest layer (your own host) outward.
The paths that produce EHOSTUNREACH, organized by cause:
| Cause | When it happens | Where to start |
|---|---|---|
| No local route | No default gateway / route deleted / interface down | ip route get |
| Failed ARP resolution | Same-segment host is down / duplicate IP / L2 break | ip neigh |
| A router on the path rejects | Router returns ICMP host/network-unreachable | traceroute |
| Firewall REJECT | A reject-with icmp-host-prohibited rule is present |
nft list ruleset |
Triage from the layer nearest your host outward. First check whether your routing table even has a route, then whether you can reach a same-segment host at L2, and finally whether something on the path is rejecting you.
A close cousin is Network is unreachable (ENETUNREACH), which shows up when there is no route to the destination network at all (for example, no default route). No route to host (EHOSTUNREACH) leans toward "the network is reachable, but the host beyond it is not". Either way, start from the local route check.
How Do You Check the Local Route?
Conclusion: Run
ip route get <dest IP>to see, in one step, which route, exit interface, and gateway the kernel would use. If it errors here, the cause is your own routing table.
First, ask the kernel how it would send to that destination.
$ ip route get 192.0.2.10
With a valid route, it shows the exit interface and gateway (or a direct link).
192.0.2.10 via 10.0.0.1 dev eth0 src 10.0.0.42 uid 1000
cache
With no route, it errors right there.
$ ip route get 192.0.2.10 RTNETLINK answers: Network is unreachable
In that case, inspect the routing table and default gateway.
$ ip route $ ip route show default
default via 10.0.0.1 dev eth0 proto static 10.0.0.0/24 dev eth0 proto kernel scope link src 10.0.0.42
If there is no default via ... line, there is no default gateway, and every destination outside the local network is unreachable. Also confirm the interface itself is not down.
$ ip -br link $ ip -br addr
eth0 UP 52:54:00:11:22:33 <BROADCAST,MULTICAST,UP,LOWER_UP>
If the interface is DOWN, bring it up with sudo ip link set eth0 up; make IP and gateway settings permanent in netplan / NetworkManager.
ip route get reproduces only the kernel's route selection without sending a packet. It shows which interface and gateway a destination maps to with no side effects, making it the ideal first move.
How Do You Check ARP on the Same Segment?
Conclusion: If the destination is on the same subnet, communication requires MAC resolution via ARP. If the peer does not answer, the neighbor table goes
FAILEDand you get No route to host. Check the state withip neigh.
If ip route get showed no via <GW> and instead dev eth0 src ... (a direct link), the destination is on the same segment. Then everything hinges on resolving its MAC via ARP (NDP for IPv6).
$ ping -c1 -W1 192.0.2.10 $ ip neigh show 192.0.2.10
If the peer answers, you get REACHABLE or STALE with a MAC. If not, it goes FAILED.
192.0.2.10 dev eth0 FAILED
FAILED means "it should be on this segment, but nobody answers ARP". Suspect the peer being down, a mistyped IP, a duplicate IP, or an L2 problem (switch / VLAN / cable). Comparing ARP to another host on the same segment helps tell your side from theirs.
$ ip neigh
10.0.0.1 dev eth0 lladdr 52:54:00:aa:bb:cc REACHABLE 192.0.2.10 dev eth0 FAILED
If the gateway (10.0.0.1) is REACHABLE while only the target is FAILED, your L2 is fine, and the problem is the peer host or its path.
The ARP table changes state over time. After seeing FAILED, recheck ip neigh a few seconds later, or actively trigger resolution with ping before reading the state, to avoid a false verdict.
What If a Router on the Path Is the Cause?
Conclusion: If No route to host appears for a destination on another network, a router on the path is likely returning ICMP host/network-unreachable. Identify the source from
ping's reply address and the hop wheretraceroutestops.
When the destination is on another subnet and both the local route and gateway are fine, the verdict is happening on the path. A ping may draw an unreachable reply from a router on your behalf.
$ ping -c2 192.0.2.10
From 10.0.0.1 icmp_seq=1 Destination Host Unreachable From 10.0.0.1 icmp_seq=2 Destination Host Unreachable
The key detail is that the reply comes From 10.0.0.1 — the router, not the destination. It means "I reached the gateway, but beyond it the host is unreachable". Find where it breaks with traceroute / mtr.
$ traceroute -n 192.0.2.10
1 10.0.0.1 0.4 ms 0.3 ms 0.3 ms 2 10.0.0.1 !H * !H
The hop that prints !H (host unreachable) is the source of the rejection. !N means network unreachable, and !X means administratively prohibited (a firewall, covered next). Once you are here, the cause is not your host — it is a device on the path or the remote side's configuration.
The trailing flags in traceroute are a shortcut: !H = host unreachable, !N = network unreachable, !X / !A = administratively prohibited (filtered). If you see the !X family, go to the firewall section next.
When a Firewall Is the Cause (icmp-host-prohibited)
Conclusion: If a firewall rejects with
reject-with icmp-host-prohibited(oricmp-host-unreachable), the client sees No route to host.tcp-resetproduces refused instead — the kind of REJECT decides the symptom.
A REJECT lets you choose what it returns to refuse the traffic. The ICMP it sends back changes what the client sees.
| REJECT type | Symptom on the client |
|---|---|
icmp-host-prohibited |
No route to host |
icmp-host-unreachable |
No route to host |
icmp-net-unreachable |
Network is unreachable |
icmp-port-unreachable (default) |
Connection refused |
tcp-reset |
Connection refused |
So if you see No route to host and the local route, ARP, and traceroute are all clean, suspect an icmp-host-prohibited-family REJECT rule. Some distributions' default iptables rules include exactly this type.
# Inspect nftables rules $ sudo nft list ruleset | grep -i -E 'reject|prohibit' # On systems using iptables $ sudo iptables -L -n -v --line-numbers
Chain INPUT (policy ACCEPT) num target prot ... destination 8 REJECT all ... reject-with icmp-host-prohibited
If a reject-with icmp-host-prohibited rule matches the traffic, it is the source. Use the position of !X in traceroute to judge whether it sits on the server or on the path. For confirming and restoring allow rules under ufw, see ufw SSH Troubleshooting.
Getting firewall rule order wrong can cut off your own connection (such as SSH). When editing rules remotely, pair the change with a scheduled rollback (for example, an at job that restores the previous ruleset after a few minutes) so you are not locked out.
Checklist When It Still Fails
Conclusion: No route to host confirms a "path / reachability" problem. Work from your host outward — local route → ARP → traceroute → REJECT rule — and the cause collapses into one of these four layers.
- [ ] Did you tell
No route to host(instant) fromtimed out(long wait)? - [ ] Did
ip route get <dest>show the route, exit interface, and gateway? - [ ] Is there a default gateway line in
ip route show default? - [ ] Is the exit interface
UP(ip -br link)? - [ ] For a same-segment target, is
ip neighshowingFAILED(ARP resolution)? - [ ] Is the
pingunreachable reply from the destination or a router (From <GW>means on the path)? - [ ] Which hop prints
!H/!N/!Xintraceroute? - [ ] Is there an
icmp-host-prohibited-family REJECT innft list ruleset/iptables -L?