"Connection refused" against "No route to host" against a timeout
Three different failures that people treat as one. Each names a different layer, and knowing which is which removes most of the guessing.
What you see
A service will not connect. The exact wording of the error is the diagnosis and is usually skipped over.
What is actually wrong
Refused means something answered and said no — the host is up, nothing is listening on that port, or a REJECT rule. No route to host is an ICMP unreachable, usually a firewall rejecting or a genuine routing problem. A timeout means nothing answered at all — a DROP rule or a machine that is not there.
Codes and articles
Fixes (3)
Find out what is not listening
Connection refused. The host is reachable — that is already established by the error itself.
See what is listening and on which address.
sudo ss -tlnpThe address column is the point. A service bound to 127.0.0.1 accepts local connections and refuses every remote one, which produces exactly this error and looks like a firewall problem.
If it is bound to loopback only, change the bind address in the service's configuration to 0.0.0.0 or the specific interface address, and restart it.
Confirm the service is running at all.
systemctl status nginx --no-pager -lCheck for a REJECT rule, which also produces a refusal.
sudo nft list ruleset 2>/dev/null | grep -i rejectsudo iptables -L -n -v | grep -i reject
Test locally to separate the service from the network.
curl -sv http://127.0.0.1:8080/ 2>&1 | head -20
sudo ss -tlnp | grep :8080Follow the packet until it stops
A timeout. Nothing answered, so the question is where it was dropped.
Establish whether the packet arrives at all.
sudo tcpdump -ni any port 8080 -c 20This settles it in one step. Packets arriving with no reply is a server or firewall problem on this machine; no packets at all is somewhere in between, and the two need completely different investigations.
Trace the path if nothing arrives.
mtr -rwzbc 20 10.0.0.20traceroute -T -p 8080 10.0.0.20
Check the local firewall for DROP rules.
sudo nft list ruleset | head -60sudo firewall-cmd --list-all 2>/dev/null
Check for asymmetric routing on a multi-homed machine — a reply leaving by a different interface is silently dropped by reverse path filtering.
ip route get 10.0.0.20sysctl net.ipv4.conf.all.rp_filter
Check MTU if it connects and then stalls on larger transfers.
ping -M do -s 1472 10.0.0.20 -c 3
Resolve the routing or the rejection
No route to host — an unreachable message came back from somewhere.
Check the local routing table and which route would be used.
ip route showip route get 10.0.0.20
If there is no default route, add one — or fix the interface configuration that should have provided it.
sudo ip route add default via 10.0.0.1 dev eth0Check ARP resolution on the local segment. An incomplete entry means the host is not answering at layer 2.
ip neigh showAn incomplete ARP entry for a machine on the same subnet points at the switch, the VLAN or a duplicate address — none of which are visible from higher-level tools.
Check for an explicit reject route, which a VPN client can leave behind.
ip route show | grep -E 'unreachable|prohibit|blackhole'Check the far end's firewall is rejecting rather than dropping — a firewalld zone set to reject produces this error rather than a timeout.
sudo firewall-cmd --get-active-zonessudo firewall-cmd --list-all
Related faults
Where this stops. This write-up was written and checked by hand. It says what each step changes, how to confirm it worked and how to reverse it, and anything destructive is flagged before you reach it. If it does not match what your machine is doing, search the Support Centre for the exact code or message — and when something needs a person, get in touch.