Network performance degradation, mysterious SSH session freezes when displaying large text blocks, and failed TLS handshakes over VPN tunnels often stem from a single underlying network issue: mismatched Maximum Transmission Unit (MTU) sizes. The MTU defines the largest packet payload (in bytes) that a network layer protocol can transmit over a physical or virtual interface without fragmenting it into smaller segments. Standard Ethernet specifies an MTU of 1500 bytes. However, when packets traverse PPPoE broadband connections, WireGuard or IPsec VPN tunnels, VLAN tags, or cloud overlay networks (such as VXLAN or GRE), tunnel encapsulation headers reduce the available MTU. The Linux ping utility provides an exact method to discover Path MTU (PMTU) and diagnose packet fragmentation.
Understanding MTU, Fragmentation, and the DF Flag
When an IP packet exceeds the MTU of any intermediate router along its transit path, the router must either fragment the packet into multiple smaller packets or drop it. In modern IPv4 networking (and mandatory in IPv6), endpoints perform Path MTU Discovery (PMTUD) by setting the Don’t Fragment (DF) bit in the IP header.
When a packet with the DF bit set encounters a router with an MTU smaller than the packet size, the router discards the packet and sends back an ICMP message: Fragmentation Needed and DF set (ICMP Type 3, Code 4). If an intermediate firewall blocks ICMP messages—a common misconfiguration known as an ICMP Black Hole—the transmitting client never discovers the smaller MTU, causing large data transfers to hang indefinitely.
By manually configuring the ping utility to send packets with the DF bit enabled at incrementing payload sizes, you can determine the exact maximum packet size that traverses the network path unfragmented.
Calculating IP and ICMP Header Overhead
When crafting test packets with ping, you specify the ICMP payload size, not the total IP frame size. You must account for protocol encapsulation overhead:
- Standard IPv4 Header: 20 bytes.
- Standard ICMP Echo Request Header: 8 bytes.
- Combined Header Overhead: 28 bytes.
Therefore, to test a standard Ethernet MTU of 1500 bytes, you subtract 28 bytes from 1500, yielding a test payload size of 1472 bytes:
Target MTU (1500 bytes) - Overhead (28 bytes) = Ping Payload (1472 bytes)
Running the MTU Test in Linux Terminal
In Linux, the ping command controls fragmentation behaviour using the -M (PMTUD strategy) parameter. Passing -M do instructs the kernel to explicitly set the Don’t Fragment (DF) bit on all outgoing ICMP packets.
To test whether a standard 1500-byte path exists between your Linux machine and a remote destination (for example, Google’s public DNS at 8.8.8.8 or your corporate gateway), run:
ping -M do -s 1472 -c 3 8.8.8.8
Interpreting the immediate output:
- Successful Response: If you receive standard replies (e.g.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=118 time=14.2 ms), packets up to 1500 bytes traverse the path cleanly without fragmentation. - Fragmentation Needed Error: If the output reads
ping: local error: message too long, mtu=1420orFrag needed and DF set, an interface or intermediate link cannot accommodate a 1500-byte frame.
Performing Binary Search to Find the Exact Path MTU
If a 1472-byte payload fails, systematically decrement the payload size to identify the threshold where packets pass through:
Step 1: Test a Common Tunnel Size (e.g. 1400 Bytes MTU)
Subtract 28 bytes from 1400 to test a 1372-byte payload:
ping -M do -s 1372 -c 2 8.8.8.8
Step 2: Narrow the Exact Byte Threshold
If 1372 bytes succeeds but 1472 bytes fails, test intermediate values (e.g. 1420 bytes, 1440 bytes, 1460 bytes) until you find the highest integer where ping succeeds.
For example, if testing with -s 1392 succeeds, but -s 1393 fails with message too long, your maximum unfragmented ICMP payload is 1392 bytes.
Step 3: Calculate Your Path MTU
Add the 28 bytes of overhead back to your winning payload:
Max Payload (1392 bytes) + Overhead (28 bytes) = Path MTU of 1420 bytes
This diagnostic confirms that an MTU of 1420 bytes is the optimal ceiling for the tested path.
Configuring MTU on Linux Network Interfaces
Once you identify your network’s true Path MTU, adjusting your Linux network interface to match this value prevents local packet fragmentation and eliminates TCP black hole connection hangs.
To inspect your current interface MTU using the ip command:
ip link show eth0
To adjust the MTU immediately on the fly (for example, setting it to 1420 bytes):
sudo ip link set dev eth0 mtu 1420
Re-running ip link show eth0 confirms that the new MTU has taken effect. For persistent configuration across system reboots, update your Netplan configuration file in /etc/netplan/ by specifying mtu: 1420 beneath the target interface block and applying it with sudo netplan apply.