Diagnosing "No route to host"

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 EHOSTUNREACH is 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 (ip command = 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 FAILED and you get No route to host. Check the state with ip 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 where traceroute stops.

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.1the 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 (or icmp-host-unreachable), the client sees No route to host. tcp-reset produces 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) from timed 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 neigh showing FAILED (ARP resolution)?
  • [ ] Is the ping unreachable reply from the destination or a router (From <GW> means on the path)?
  • [ ] Which hop prints !H / !N / !X in traceroute?
  • [ ] Is there an icmp-host-prohibited-family REJECT in nft list ruleset / iptables -L?

Next Reading