Skip to content
QKQuickKit日本語

Ping works but large transfers hang: troubleshooting MTU, MSS, and PMTUD

When page loads or scp stall while ping and SSH work, suspect a Path MTU Discovery failure: confirm it with DF-set pings, compute the MSS, and know what MSS clamping does not fix.

Sources and commands checked:

Ping answers and SSH logs in, yet web pages stall halfway, and scp or large mail transfers freeze. That combination is the typical sign that large packets are dropped somewhere on the path and the sender is never told. RFC 2923 §2.1 calls this a Path MTU Discovery (PMTUD) "black hole": pings and interactive TCP connections work, while bulk transfers fail with the first large packet.

How PMTUD works, and how it fails

  • IPv4: the sender sets the DF (Don't Fragment) bit. A router that cannot forward a packet larger than the next link's MTU returns ICMP Destination Unreachable Type 3 Code 4 (Fragmentation Needed and DF set) and puts that link's MTU in the Next-Hop MTU field (RFC 1191 §4). The sender then sends smaller packets.
  • IPv6: only the source fragments, never a router on the path (RFC 8200 §4.5). For a packet that is too large, a router returns ICMPv6 Type 2 (Packet Too Big) with the next link's MTU (RFC 4443 §3.2, RFC 8201).
  • When a firewall drops these ICMP / ICMPv6 messages, the sender keeps sending large packets that never arrive, retransmits, and eventually times out (RFC 2923 §2.1). RFC 4890 §4.3.1 lists Packet Too Big among the ICMPv6 messages a firewall must not drop.

Confirming it: DF-set pings of decreasing size

The IP packet is the ping data length plus the ICMP header (8 bytes) plus the IP header (20 bytes for IPv4, 40 for IPv6). On a path with an MTU of 1500, 1472 data bytes fit exactly for IPv4 and 1452 for IPv6.

# Linux (iputils): -M do sets DF, -s sets the data length
ping -M do -s 1472 -c 3 192.0.2.10
ping -M do -s 1464 -c 3 192.0.2.10   # fits a 1492-byte path (PPPoE, for example)
ping -6 -M do -s 1452 -c 3 2001:db8::10

# Windows: /f sets DF (IPv4 only), /l sets the data length
ping /f /l 1472 192.0.2.10

Reading the results:

  • 1472 fails and smaller sizes succeed: some link on the path has an MTU below 1500. The largest data length that passes plus 28 (plus 48 for IPv6) is an estimate of the path MTU.
  • Linux ping prints Frag needed and DF set (mtu = 1400) (for IPv6, Packet too big: mtu=1400): a router reported the next link's MTU through ICMP. PMTUD itself works, and the reported mtu is your lead.
  • It prints local error: message too long, mtu=1500: the packet exceeds the MTU your own host knows (the interface MTU or a path MTU it has learned), so it was stopped before sending.
  • Large sizes get no answer at all (timeouts) while small sizes pass: large packets are dropped and no ICMP comes back, which strongly suggests a black hole. A target or device that rate-limits ping can look similar, so compare with another destination.

tracepath (iputils) walks the path and prints the MTU it learns along the way (pmtu), which shows where it drops.

tracepath -n 192.0.2.10

Where you can capture packets, check whether the ICMP messages arrive (tcpdump / libpcap filters):

tcpdump -n 'icmp[icmptype] == icmp-unreach and icmp[icmpcode] == 4'
tcpdump -n 'icmp6[icmp6type] == icmp6-packettoobig'

Paste a captured IPv4 ICMP message (the bytes starting at Type) into ICMP Decoder to read its type and code. The tool does not show the Next-Hop MTU as a field of its own: for Type 3 Code 4, it is the low-order 16 bits (the last four hex digits) of the four bytes shown as "Rest of header" (RFC 1191 §4; for example, 00000578 → 0x0578 = 1400). A value of 0 means the router did not report its MTU (RFC 1191 §3).

ICMP Decoder handles ICMPv4 only and cannot decode an ICMPv6 Packet Too Big message. Look up ICMPv6 types and codes in ICMP & ICMPv6 Type/Code Reference.

Computing the MSS

The value advertised in the TCP MSS (Maximum Segment Size) option is the effective MTU minus the fixed IP and TCP headers (RFC 9293 §3.7.1).

Path MTUIPv4 MSS (−40)IPv6 MSS (−60)
1500 (standard Ethernet)14601440
1492 (PPPoE)14521432
1280 (IPv6 minimum link MTU)12401220

The table shows the MSS a host advertises in its SYN. The data actually carried per segment (the effective send MSS) is the smaller of the MSS received from the peer and what the sender itself can send, minus any TCP options and IPv4 options or IPv6 extension headers (RFC 9293 §3.7.1). For example, with the Timestamps option (10 bytes per RFC 7323 §3.2, or 12 with the two NOPs its Appendix A recommends) on every segment, a peer advertising 1460 receives at most 1448 data bytes per segment.

For paths through a tunnel (GRE, IPsec, VXLAN, WireGuard, and others), MTU/MSS Calculator works out the MTU and MSS from the encapsulation overhead.

Workaround: MSS clamping, and its limits

When ICMP cannot be let through on the path, a router can rewrite the MSS in TCP SYN segments ("MSS clamping"). With Linux iptables (the TCPMSS target in iptables-extensions(8)):

iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
  • --clamp-mss-to-pmtu limits the MSS to the path MTU − 40 (IPv4) or − 60 (IPv6). The same document warns that it may not work as desired on asymmetric routes whose path MTUs differ.
  • MSS clamping affects TCP only. UDP traffic, including QUIC (HTTP/3) and many VPNs, is not made smaller. For datagram transports, RFC 8899 (DPLPMTUD) describes path MTU discovery in the packetization layer.
  • The real fix is to stop dropping ICMP Fragmentation Needed and Packet Too Big.

Limits and caveats

  • The size test measures ICMP Echo. A device that limits or deprioritizes ICMP Echo can make the result differ from what TCP sees.
  • Paths can change by destination and over time; test against the destination that actually fails.
  • Check your vendor's official documentation for how to configure MSS clamping on other devices; this guide shows only the Linux example.

Sources (primary references)