Troubleshoot Packet Loss in Linux

Tested on RHEL 10.2 (Coughlan) — vm1.lab.example (192.168.56.116); lab peer 192.168.56.220 on host-only enp0s8; default gateway 10.0.2.2 on enp0s3
Package iputils 20240905-5.el10
mtr 0.95-11.el10
ethtool 6.15-2.el10
tcpdump 4.99.4-10.el10
iproute 6.17.0-2.el10
Applies to Ubuntu, Debian, Kali Linux, Linux Mint, Pop!_OS, Raspberry Pi OS, elementary OS, Zorin OS, Parrot OS, MX Linux, RHEL, Rocky Linux, AlmaLinux, Oracle Linux, CentOS Stream, Fedora, Arch Linux
Privilege Normal user for ping and read-only ip / ethtool; sudo or root for tcpdump, tc, and changing interface settings
Scope Diagnose Linux network packet loss and drops using ping statistics, mtr per-hop loss, ip -s link counters, ethtool link state, MTU tests, and tcpdump on ICMP. Does not cover application-level retries, Wi-Fi driver tuning, or full traceroute reference.
Related guides Network is unreachable
Destination host unreachable
Test port connectivity
traceroute command
ip route command

Applications stutter, SSH sessions freeze, and ping prints gaps in the sequence numbers — classic signs of packet loss. On Linux you confirm the drop rate first, then walk outward from your own NIC toward the destination until the loss appears on a specific hop or interface counter.

The workflow below uses ping for a quick percentage, mtr to locate the hop, kernel and driver counters for local drops, MTU probes for silent black holes, and tcpdump when you need to see whether replies leave the wire.


Confirm packet loss with ping

ping is the fastest way to turn a vague “network feels bad” report into a number. Send enough probes that a few dropped packets show up in the summary — ten packets is a minimum; twenty or more is better on flaky links.

Test a host on your LAN first so you have a baseline on a short path:

bash
ping -c 10 -i 0.2 192.168.56.220

When the link is healthy, every sequence number gets a reply and the summary shows 0% packet loss:

output
--- 192.168.56.220 ping statistics ---
10 packets transmitted, 10 received, 0% packet loss, time 1823ms
rtt min/avg/max/mdev = 0.594/1.120/2.764/0.584 ms

When loss is present, missing replies show as jumps in icmp_seq and a non-zero loss percentage. On the lab host I briefly applied tc netem to reproduce drops, then ran the same count:

bash
ping -c 20 -i 0.3 192.168.56.220
output
--- 192.168.56.220 ping statistics ---
20 packets transmitted, 16 received, 20% packet loss, time 5746ms
rtt min/avg/max/mdev = 0.635/0.899/1.240/0.195 ms

Remove lab-only traffic shaping when you are done (sudo tc qdisc del dev enp0s8 root).

Read the summary line together: 16 received out of 20 transmitted means four probes never got an echo reply. The rtt line only averages replies that arrived — it says nothing about how many were lost.

Repeat the same count against your default gateway so you can compare LAN versus first-hop loss later:

bash
ping -c 20 -i 0.2 10.0.2.2
output
--- 10.0.2.2 ping statistics ---
20 packets transmitted, 20 received, 0% packet loss, time 3884ms
rtt min/avg/max/mdev = 0.422/0.690/1.679/0.280 ms

0% packet loss to the gateway with loss to a LAN peer points at the local segment or the peer — not your upstream ISP. Loss on both usually means a problem on your host or the shared outbound interface.


Locate the problem with mtr

mtr (My Traceroute) sends repeated probes to each hop and prints loss and latency per hop — more useful than a one-shot traceroute when loss is intermittent.

Run a report-mode trace to a destination that showed loss in ping. -rw prints wide, parseable output; -c sets how many probes per hop:

bash
mtr -rw -c 5 192.168.56.220

On a clean one-hop LAN path, loss stays at 0.0% on the only hop:

output
Start: 2026-08-22T09:11:04+0530
HOST: vm1.lab.example Loss%   Snt   Last   Avg  Best  Wrst StDev
  1.|-- 192.168.56.220   0.0%     5    2.5   1.5   0.6   2.5   0.8

Re-run mtr while the path is lossy — the first hop line carries the percentage:

bash
mtr -rw -c 10 192.168.56.220
output
Start: 2026-08-22T09:11:42+0530
HOST: vm1.lab.example Loss%   Snt   Last   Avg  Best  Wrst StDev
  1.|-- 192.168.56.220  20.0%    10    2.2   1.5   1.1   2.2   0.3

The hop where Loss% first climbs is where you focus next — local NIC, switch port, or an upstream router. If only the last hop shows loss, the target or its edge network may be rate-limiting ICMP even when TCP works.

mtr needs the mtr package on minimal installs (dnf install mtr or apt install mtr).


Check interface errors and drops

Kernel counters on the outbound interface tell you whether frames are being discarded before they leave the host. Use the interface that carries traffic to the failing destination — here the lab LAN NIC:

bash
ip -s link show enp0s8
output
3: enp0s8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
    link/ether 08:00:27:c4:4f:20 brd ff:ff:ff:ff:ff:ff
    RX:  bytes packets errors dropped  missed   mcast
        708354    5419      0       0       0     162
    TX:  bytes packets errors dropped carrier collsns
      29402843   24031      0       3       0       0

Focus on the counter columns:

  • errors — malformed frames or driver-level receive/transmit faults
  • dropped — packets discarded in the kernel or qdisc (buffer pressure, policy)
  • carrier / collsns — physical-layer problems on half-duplex or bad links

A few historical TX dropped values with zero errors and clean ping often mean past congestion, not an active fault. Rising counters while you reproduce loss tie the problem to this NIC or its queue discipline.

Resetting counters is optional — note the values, reproduce the issue, and read them again:

bash
sudo ethtool -S enp0s8 | head -20
output
NIC statistics:
     rx_packets: 5418
     tx_packets: 23945
     rx_errors: 0
     tx_errors: 0
     tx_dropped: 0
     rx_crc_errors: 0
     rx_frame_errors: 0

rx_crc_errors or rx_frame_errors climbing points at cable, SFP, or duplex mismatch — pair with ethtool link checks in the next section.


Before you blame routing or remote firewalls, confirm the NIC negotiates the speed and duplex you expect and that the kernel still sees carrier.

bash
sudo ethtool enp0s8
output
Settings for enp0s8:
	Speed: 1000Mb/s
	Duplex: Full
	Auto-negotiation: on
	Link detected: yes

Link detected: no with an UP interface in ip link usually means unplugged cable, failed SFP, or a switch port down — ping loss to every neighbor follows. Speed or Duplex stuck at 10Mb/s / Half on a gigabit link can mean a bad patch lead or autoneg failure.

Scroll to the bottom of ethtool output for Link detected — some drivers print dozens of capability lines first. For driver-specific drop reasons, use statistics mode:

bash
sudo ethtool -S enp0s8 | grep -E 'drop|error|miss'

No matches or all zeros support a clean local link; non-zero *_drop or *_error counters while loss is active deserve a cable, switch port, or driver update check.


Check MTU problems

Oversized packets that cannot traverse the path are dropped without a normal ICMP reply — ping looks like random loss and TCP may hang on large transfers. Test whether the path accepts full-size frames with do-not-fragment probes.

Ethernet MTU 1500 means an ICMP payload of 1472 bytes (1500 minus 20-byte IP header and 8-byte ICMP header):

bash
ping -c 3 -M do -s 1472 192.168.56.220
output
--- 192.168.56.220 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms

All three replies confirm the LAN path handles standard MTU.

Push past the interface MTU and the kernel refuses to send — this is local, not upstream:

bash
ping -c 2 -M do -s 2000 192.168.56.220
output
ping: sendmsg: Message too long
--- 192.168.56.220 ping statistics ---
2 packets transmitted, 0 received, +2 errors, 100% packet loss, time 1029ms

Message too long means the payload exceeded enp0s8's MTU before the packet left the host. For path MTU discovery toward remote networks, step -s down from 1472 until probes succeed, or use tracepath DESTINATION for a scripted PMTU walk.

VPN tunnels and PPP interfaces often use MTU 1400 or lower — if only large transfers fail while small ping works, compare ip link show MTU on the tunnel against inner paths.


Inspect traffic with tcpdump

When ping reports loss but interface counters stay flat, capture packets on the wire to see whether requests leave and whether replies return.

Start a short capture on the interface toward the peer, filtered to ICMP between the two hosts:

bash
sudo timeout 5 tcpdump -ni enp0s8 icmp and host 192.168.56.220

In another session (or background the capture first), send a few pings:

bash
ping -c 3 192.168.56.220

A healthy exchange shows paired requests and replies:

output
09:11:30.310216 IP 192.168.56.116 > 192.168.56.220: ICMP echo request, id 47, seq 1, length 64
09:11:30.310824 IP 192.168.56.220 > 192.168.56.116: ICMP echo reply, id 47, seq 1, length 64
09:11:31.332993 IP 192.168.56.116 > 192.168.56.220: ICMP echo request, id 47, seq 2, length 64

Requests without matching replies mean loss on the return path or filtering at the peer. No requests at all means the traffic left on a different interface — recheck ip route get PEER before you chase the wrong NIC.

0 packets dropped by kernel in the tcpdump footer means the capture tool kept up; if that counter rises, use -c to limit packets or narrow the filter.


Determine whether loss is local or upstream

Compare three targets in order: a LAN peer, your default gateway, and a remote IP. The first hop where loss appears tells you which layer to fix.

Test target Command example Loss here suggests
LAN peer on same subnet ping -c 20 192.168.56.220 Cable, switch port, NIC, or peer host
Default gateway ping -c 20 10.0.2.2 Local router, NAT, or wrong outbound interface
Remote public IP ping -c 20 1.1.1.1 ISP, upstream congestion, or ICMP filtering

Run the LAN baseline:

bash
ping -c 10 -W 2 192.168.56.220
output
--- 192.168.56.220 ping statistics ---
10 packets transmitted, 10 received, 0% packet loss, time 1823ms

Test the gateway on the interface that owns the default route:

bash
ping -c 10 -W 2 10.0.2.2
output
--- 10.0.2.2 ping statistics ---
10 packets transmitted, 10 received, 0% packet loss, time 3884ms

Probe a remote address last — many networks block ICMP toward the internet even when TCP works:

bash
ping -c 10 -W 2 1.1.1.1
output
--- 1.1.1.1 ping statistics ---
10 packets transmitted, 0 received, 100% packet loss, time 9248ms

0% on LAN and gateway but 100% to 1.1.1.1 often means upstream ICMP drop, not necessarily broken TCP. Confirm with mtr if any hops reply, or test TCP with curl -sS --connect-timeout 5 https://1.1.1.1 and port checks on the service you care about.

If mtr shows loss starting at hop 1, fix local link, driver, and tc shaping before you open an ISP ticket. Artificial loss from tc qdisc netem in a lab shows the same pattern — remove test qdiscs with sudo tc qdisc del dev DEV root when finished.


Troubleshooting

Symptom Likely cause Fix
ping loss only to one LAN IP Peer firewall, overloaded host, or bad patch lead tcpdump on both sides; check peer iptables / nft; swap cable or switch port
Loss on first mtr hop only Local NIC, driver, Wi-Fi, or tc netem ethtool, ip -s link, remove tc rules; update firmware or driver
TX dropped rising on one interface Qdisc backlog or RPS overload Check fq_codel drops; reduce parallel streams; tune NIC ring buffers per vendor docs
Large transfers fail, small ping works MTU mismatch on VPN or tunnel Lower interface MTU or fix PMTU; test with ping -M do -s stepping down
ping: sendmsg: Message too long Payload larger than interface MTU Reduce -s or raise MTU only if every hop supports it
100% loss to internet, 0% on LAN ICMP blocked upstream Verify TCP/UDP; use mtr and application metrics, not ping alone
Link detected: no Unplugged cable or down switch port Physical layer first; then nmcli device reapply or reconnect profile

References


Summary

Packet loss on Linux starts with a counted ping — the summary line gives you a percentage and missing sequence numbers tell you the failure is real, not a single slow reply. Run the same test against a LAN neighbor and your default gateway before you blame a remote network.

mtr -rw -c maps loss to a hop. Combined with ip -s link and ethtool, you can tell whether counters climb on your own NIC or the loss only appears past the gateway. MTU issues show up as Message too long locally or as 100% loss only on large ping -M do -s probes. tcpdump settles arguments about whether echo requests and replies actually cross the interface you think they use.

The decisive pattern is where loss begins: same-subnet peers implicate L2 or the local stack; gateway-only loss implicates your router or outbound policy; clean LAN and gateway with failed remote ICMP often means filtering, not a dead path — verify with TCP and the services you run in production. When routing errors accompany loss, continue with network is unreachable or destination host unreachable for paths that fail before packets leave the host.


Frequently Asked Questions

1. How do I check packet loss on Linux?

Run ping with a packet count, for example ping -c 20 DESTINATION. The summary line lists packets transmitted, received, and the packet loss percentage. Repeat the test for a LAN peer, your default gateway, and a remote IP to see where loss starts.

2. What is an acceptable packet loss percentage?

On a healthy LAN, expect 0% loss. On the public internet, brief spikes under 1% are common on busy paths. Sustained loss above a few percent on a stable link, or loss that matches application timeouts, warrants investigation with mtr and interface counters.

3. What is the difference between ping packet loss and interface drops?

Ping loss is measured end to end — a missing ICMP echo reply. Interface drops in ip -s link or ethtool -S are local counters on one NIC. You can have 0% interface drops while ping shows loss because a router, firewall, or congested hop dropped traffic upstream.

4. Should I use mtr or traceroute for packet loss?

Use mtr when you need per-hop loss and latency over many probes. traceroute shows the path once per hop; mtr combines traceroute with repeated pings so you can see which hop first reports Loss%. Install mtr from your distribution packages if it is not already present.

5. Can firewalls cause 100% ping loss but working TCP?

Yes. Many networks block or rate-limit ICMP while HTTP, SSH, and DNS over TCP or UDP still work. Treat ping and mtr as hints, not the only signal — confirm with tcpdump on the interface and a TCP test such as curl or nc when ICMP is filtered.
Deepak Prasad

R&D Engineer

Founder of GoLinuxCloud with more than 15 years of expertise in Linux, Python, Go, Laravel, DevOps, Kubernetes, Git, Shell scripting, OpenShift, AWS, Networking, and Security. With extensive experience, he excels across development, DevOps, networking, and security, delivering robust and efficient solutions for diverse projects.

  • Go (programming language)
  • Python (programming language)
  • DevOps
  • Computer Security
  • Cloud Computing
  • Kubernetes
  • Linux
  • Ansible (software)