How to Troubleshoot Network Connectivity
Diagnose Linux network problems layer by layer using ip, ping, traceroute, ss, and dig — from interface state to DNS resolution.
Before you start
- ▸A terminal with sudo or root access
- ▸iproute2 installed (provides ip, ss — present by default on all major distros)
- ▸Basic familiarity with reading command output
Network problems have a reputation for being mysterious, but they almost always fail at a specific layer: the interface is down, the route is missing, the firewall is blocking, or DNS is broken. Working through those layers in order — instead of guessing — gets you to the answer fast. This guide walks through a repeatable diagnostic sequence using tools available on every modern Linux system.
The Layered Diagnostic Method
Think of network connectivity as a stack. Each layer depends on the one below it, so start at the bottom and work up:
- Physical / interface — is the link up and does the interface have an address?
- IP / routing — can the kernel reach the destination network?
- End-to-end reachability — can packets actually arrive at a remote host?
- Transport / sockets — is the right service listening on the right port?
- DNS — is name resolution working correctly?
Step 1: Check Interface State and Addressing
The ip command from the iproute2 package replaces the old ifconfig. Use it to confirm your interface exists, is UP, and has an address.
ip link show
Look for the interface name (e.g., eth0, enp3s0, wlan0) and check that it reads state UP. A result of state DOWN or NO-CARRIER points to a cable, driver, or hardware problem before you go any further.
ip addr show
Confirm the interface has a valid IP address. If you see only a link/ether line and no inet address, the interface has no IP — either DHCP failed or no static address was assigned.
Bring Up a Down Interface
If the interface is down, bring it up manually to test (replace enp3s0 with your interface name):
sudo ip link set enp3s0 up
Then request a DHCP lease. On systems using NetworkManager (most desktops and RHEL/Fedora servers):
nmcli device connect enp3s0
On minimal systems without NetworkManager, trigger a DHCP request directly:
sudo dhclient enp3s0
Step 2: Verify the Routing Table
Even with a valid IP address, packets go nowhere without a default gateway. Check the routing table:
ip route show
You should see a line beginning with default via followed by your gateway address — typically something like 192.168.1.1. If there is no default route, packets destined for outside your local subnet will be dropped silently by the kernel.
Add a missing default route temporarily (swap in your real gateway IP):
sudo ip route add default via 192.168.1.1 dev enp3s0
This change does not survive a reboot. Fix it permanently through your network manager or configuration files (/etc/network/interfaces on Debian/Ubuntu, NetworkManager profiles on Fedora/RHEL, /etc/systemd/network/ on systemd-networkd setups).
Step 3: Test Reachability with ping
Start close and work outward. First, ping the loopback address to confirm the IP stack itself is functional:
ping -c 4 127.0.0.1
Then ping your default gateway to test local network reachability:
ping -c 4 192.168.1.1
If that succeeds, ping a public IP address to test routing to the internet without involving DNS:
ping -c 4 8.8.8.8
If the gateway ping fails but your own interface is up, suspect a firewall on the gateway, a VLAN mismatch, or a bad cable. If the public IP ping fails but the gateway responds, suspect a routing or NAT problem upstream.
Step 4: Trace the Path with traceroute
When ping to a remote host fails or shows high latency, traceroute (or the more informative mtr) maps every hop between you and the destination.
Install if needed:
# Debian/Ubuntu
sudo apt install traceroute mtr
# Fedora/RHEL
sudo dnf install traceroute mtr
# Arch
sudo pacman -S traceroute mtr
traceroute 8.8.8.8
Each line is one hop. * * * means the router at that hop is not responding to probes — this is common and does not always indicate a break. Look for the point where responses stop entirely; that is where the path fails. For a live, continuously updating view:
mtr --report-cycles 20 8.8.8.8
mtr combines ping and traceroute and is far more useful for intermittent problems because it shows packet loss per hop over time.
Step 5: Inspect Sockets and Listening Services with ss
ss replaces netstat and reads socket state directly from the kernel. Use it when you can reach a host but a specific service is not responding.
List all listening TCP and UDP sockets with the process that owns them:
ss -tulnp
-tTCP,-uUDP-llistening sockets only-nnumeric ports (no service name lookup)-pshow the owning process
If the service you expect (say, port 80 for a web server) is not in the list, the service is not running or is bound to a different port. Check with systemctl status nginx (or whichever service) and look at its logs. If the port is listed but you still cannot connect from a remote host, the problem is almost certainly a firewall rule.
Quick Firewall Check
Verify whether a firewall is actively blocking the port. On systems using nftables directly:
sudo nft list ruleset
On systems using firewalld (Fedora, RHEL, Rocky):
sudo firewall-cmd --list-all
On systems using ufw (Ubuntu):
sudo ufw status verbose
Step 6: Diagnose DNS with dig
DNS failures look like connectivity failures because domain names stop resolving, but the network itself is fine. If ping 8.8.8.8 works but ping google.com fails, DNS is the culprit.
Install dig if it is not present:
# Debian/Ubuntu
sudo apt install dnsutils
# Fedora/RHEL
sudo dnf install bind-utils
# Arch
sudo pacman -S bind
Query your current resolver:
dig google.com
A working response includes a non-empty ANSWER SECTION and a status of NOERROR. If you get SERVFAIL, NXDOMAIN, or a timeout, try querying a known-good public resolver directly to isolate whether the problem is your configured resolver or the domain itself:
dig @8.8.8.8 google.com
dig @1.1.1.1 google.com
If the direct query works but your default resolver fails, update /etc/resolv.conf or fix the resolver setting in NetworkManager:
nmcli con mod "Your Connection Name" ipv4.dns "8.8.8.8 1.1.1.1"
nmcli con up "Your Connection Name"
On systems using systemd-resolved, check resolver status and configured DNS servers with:
resolvectl status
Verification: End-to-End Test
Once each layer checks out, confirm full connectivity with a name-based ping and an actual HTTP request:
ping -c 4 google.com
curl -I https://google.com
A 200 or 301 HTTP response from curl confirms that IP routing, DNS, and TCP connectivity are all working together.
Troubleshooting Reference
| Symptom | Likely Layer | First Command |
|---|---|---|
| No IP address on interface | Interface / DHCP | ip addr show |
| Can ping gateway, not internet | Routing / upstream | ip route show |
| Can ping IP, not hostname | DNS | dig hostname |
| Can reach host, service times out | Transport / firewall | ss -tulnp |
| Intermittent loss to remote host | Routing / intermediate hop | mtr hostname |
Frequently asked questions
- Why does ping to a public IP work but ping to a hostname fail?
- This is a DNS-only failure. Your IP routing is fine, but your configured DNS resolver is not returning answers. Test with 'dig @8.8.8.8 hostname' to confirm, then update your resolver settings.
- What does 'state NO-CARRIER' mean in ip link show?
- NO-CARRIER means the interface is administratively up but the physical or logical link is not detected — typically a disconnected cable, a disabled switch port, or a wireless adapter with no association.
- traceroute shows '* * *' at every hop after my gateway. Is the path broken?
- Not necessarily. Many routers and firewalls silently drop the UDP or ICMP probes that traceroute uses while still forwarding normal traffic. Try 'traceroute -T' to use TCP probes, which are less likely to be filtered.
- ss shows the service is listening, but I still cannot connect from another machine. Why?
- The most common cause is that the service is bound to 127.0.0.1 (loopback only) rather than 0.0.0.0 or the specific interface address. Check the Local Address column in 'ss -tulnp' output. A firewall rule is the second most likely cause.
- Should I use ping6 and ip -6 for IPv6 problems?
- The modern 'ip' command handles both IPv4 and IPv6; use 'ip -6 addr show' and 'ip -6 route show' for IPv6 details. For pinging IPv6, use 'ping -6 hostname' — most distros alias ping6 to this already.
Related guides
Common Linux Network Ports Reference
Learn Linux port ranges, read /etc/services, find what's listening with ss and nmap, and apply solid firewall rules to expose or block the right ports.
How to Configure a Static IP on Linux
Configure a static IP on Linux using Netplan, NetworkManager (nmcli), or systemd-networkd across Ubuntu, Fedora, Debian, and Arch with verified steps.
How TCP/IP Networking Actually Works
Trace a TCP connection from socket to wire: routing table lookups, ARP, the three-way handshake, MTU/PMTUD, and how NAT rewrites packets on a Linux gateway.
An Introduction to TCP/IP
Learn how TCP/IP works — IP addressing, routing, TCP vs UDP, ports, DNS, and the layered model — with practical Linux commands to see it all in action.