Linux  ·  medium  ·  Networking, DNS & SSH

Connections establish then hang — MTU and path MTU discovery

Small packets pass and large ones do not. Everything that involves a handshake works; everything that involves data stalls.

What you see

SSH connects and hangs after the banner. Web pages start loading and stop. Small files copy, large ones stall at the same point every time. Ping works perfectly.

What is actually wrong

A link in the path with a smaller MTU, combined with ICMP being blocked so the sender never learns about it. Common over VPNs, PPPoE and tunnels, where the encapsulation overhead reduces the usable size.

Codes and articles

MTUPMTUpacket too bighangs on large transferssh hangs after banner

Fixes (2)

Measure the largest packet that gets through
Root shell20 minuteslow riskreversible

Confirm the diagnosis before changing any interface.

  1. Send progressively larger packets with fragmentation forbidden. The largest that succeeds, plus 28, is the path MTU.

    Shell
    ping -M do -s 1472 -c 2 8.8.8.8ping -M do -s 1400 -c 2 8.8.8.8ping -M do -s 1300 -c 2 8.8.8.8

    1472 plus 28 bytes of headers is 1500, the standard ethernet MTU. If 1472 fails and 1400 succeeds, something in the path is smaller than 1500 and that is the entire fault.

  2. Check the interface's configured MTU.

    Shell
    ip -brief link showip link show dev eth0 | grep -o 'mtu [0-9]*'
  3. Check whether the kernel has learned a lower path MTU for that destination.

    Shell
    ip route get 8.8.8.8ip route show cache
  4. Confirm ICMP is not being filtered — path MTU discovery depends entirely on ICMP type 3 code 4 getting back.

    Shell
    sudo tcpdump -ni any icmp -c 10
Confirm it workedYou have a number: the largest working payload size.
If you need to undo itNothing was changed.
Set the MTU and clamp the segment size
Root shell25 minutesmedium riskreversible

You know the working size, or a tunnel is involved.

  1. Test the value temporarily before making it permanent.

    Shell
    sudo ip link set dev eth0 mtu 1420
  2. For WireGuard, 1420 is the usual value; for PPPoE, 1492; for a GRE tunnel, 1476. Start from the standard for the encapsulation rather than guessing.

  3. Make it permanent in the network configuration — netplan, NetworkManager or the interface file, depending on the distribution.

    Shell
    sudo nmcli connection modify 'Wired connection 1' 802-3-ethernet.mtu 1420sudo nmcli connection up 'Wired connection 1'
  4. On a router or a machine that forwards traffic, clamp the TCP maximum segment size so clients behind it are corrected automatically.

    Shell
    sudo nft add rule inet filter forward tcp flags syn tcp option maxseg size set rt mtu

    MSS clamping fixes every client behind the router without touching any of them. It is the standard answer for a site behind a tunnel and it avoids having to set the MTU on each machine.

  5. Make sure ICMP is permitted through the firewall in both directions — blocking it wholesale is what turned a small MTU into a hang rather than a slow transfer.

    Shell
    sudo nft list ruleset | grep -i icmp
Confirm it workedA large transfer completes at full speed and ping -M do succeeds at the new size.
Shell
ping -M do -s $((1420-28)) -c 3 8.8.8.8
If you need to undo itip link set dev eth0 mtu 1500 restores the default until the next reboot; revert the permanent configuration to undo it fully.

Where this stops. This write-up was written and checked by hand. It says what each step changes, how to confirm it worked and how to reverse it, and anything destructive is flagged before you reach it. If it does not match what your machine is doing, search the Support Centre for the exact code or message — and when something needs a person, get in touch.