Diagnose Network Connectivity Step by Step: ping, mtr, nc, tcpdump
"The network is down" tells you nothing. Work from the bottom layer up, one test per step, and the broken layer identifies itself.
The ladder
# 1. Do I have an address and a route?
ip -br addr
ip route
# 2. Can I reach my router?
ping -c3 192.168.1.1 # your default gateway from "ip route"
# 3. Can I reach the internet by IP (no DNS involved)?
ping -c3 1.1.1.1
# 4. Does DNS work?
dig +short example.com
# 5. Can I open the port?
nc -zv example.com 443
# 6. Does the application answer?
curl -v https://example.com/
The first step that fails is where to look. A pass at step 3 and fail at step 4 means DNS, not "no internet".
Read the error: it tells you what's wrong
| Message | What it means | Look at |
|---|---|---|
| Connection refused | The host answered, but nothing listens on that port (or the firewall rejects) | Is the service running? Is it bound to the right address? |
| Connection timed out | Packets are silently dropped or never answered | Firewall, wrong IP, routing, host is down |
| No route to host | No path, or the router said unreachable | Routes, gateway, VLAN |
| Name or service not known | DNS can't resolve the name | DNS troubleshooting |
| Network is unreachable | You have no route to that network at all | ip route, interface down |
| Certificate errors | TCP worked; TLS did not | Expired cert, wrong name, wrong SSL mode behind a proxy |
"Refused" versus "timed out" is the most useful distinction: refused means the packet arrived, timed out means it probably didn't.
Is a port open?
nc -zv HOST 443 # TCP test
timeout 3 bash -c '</dev/tcp/HOST/443' && echo open || echo closed # without nc
curl -sv --connect-timeout 5 telnet://HOST:443
On the server, confirm the service is listening on the right address (see which process uses a port):
sudo ss -tlnp | grep ':443'
If the port is open on the server but unreachable from outside, check both the OS firewall and your provider's cloud firewall.
Where along the path is the problem?
traceroute example.com # or: tracepath example.com
mtr -rwbzc 100 example.com # report mode, 100 probes
mtr combines ping and traceroute. Read the Loss% column carefully:
- Loss at one middle hop but 0% at the final hop is harmless. Routers often rate-limit replies to probes while forwarding your traffic fine.
- Loss that starts at a hop and continues to the end is real packet loss from that hop onward.
- A big jump in latency that stays high from one hop onward marks a slow link.
Windows equivalents:
Test-NetConnection example.com -Port 443 -TraceRoute
tracert example.com
pathping example.com
Packet loss and latency
ping -c 50 example.com # check "% packet loss" and the min/avg/max line
Steady loss of even a few percent hurts TCP badly. Test the local link first (router), then the internet, to see which part is lossy.
MTU problems: some sites work, some hang
Symptom: small pages load but big ones, uploads or HTTPS handshakes freeze, often behind a VPN or PPPoE. Test the largest packet that fits without fragmenting:
ping -M do -s 1472 example.com # Linux: 1472 + 28 header bytes = 1500
ping -M do -s 1400 example.com # lower until it passes
ping example.com -f -l 1472
If 1472 fails but a smaller size works, the path MTU is lower. Set the interface (or VPN) MTU a little lower; WireGuard's default of 1420 exists for exactly this reason.
Packet capture: the final answer
When you can't tell whether packets arrive, look at the wire on the server:
sudo tcpdump -ni any 'host 203.0.113.5 and tcp port 443'
sudo tcpdump -ni any 'tcp dst port 80 and tcp[tcpflags] & tcp-syn != 0' # incoming connection attempts
- No SYN packets arrive: something upstream blocks or misroutes the traffic (cloud firewall, wrong DNS record, NAT).
- SYN arrives, no SYN-ACK leaves: local firewall or no listener.
- SYN-ACK leaves, but connection hangs: return path problem (asymmetric routing, rp_filter, wrong gateway).
This test is how the cause of a Cloudflare 522 usually gets found.
Local firewall check
sudo ufw status verbose
sudo iptables -S | head -30
sudo nft list ruleset | head -50
Remember that Docker bypasses UFW for published ports.
Don't forget the simple things
- Cable, Wi-Fi band, router reboot, the right VLAN.
- Wrong IP or subnet mask (
ip -br addr). See subnetting basics. - Another device with the same IP (look for ARP conflicts in the logs).
- A VPN or proxy changing routes or DNS.
- IPv6 half-broken: test with
curl -4andcurl -6to see which family fails.