Writing

SSH connects, then hangs: it is almost always MTU

Published 15 September 2026

You log in fine. The prompt appears. Then the first command that prints more than a screenful freezes, and the session is dead. Nothing is wrong with SSH. Something on the path is silently discarding your large packets, and you can confirm it in about thirty seconds.

The tell: small things work, big things vanish

This failure has a distinctive shape. Anything small succeeds; anything large disappears without an error. If two or more of these are true, stop looking at the application:

That last one is the giveaway. A VPN or tunnel adds its own headers to every packet, so the room left for your data shrinks, and something on the path is not telling anyone.

Confirm it in thirty seconds

Send one packet that is too big to fragment. If a normal ping succeeds and this one fails, you have your answer.

The flags differ per platform, which is where most of the wasted time goes: the Linux form is what every forum post quotes, and it is silently wrong on macOS and Windows:

Linux     ping -M do -s 1472 -c 3 <host>
macOS     ping -D    -s 1472 -c 3 <host>
Windows   ping -f    -l 1472    <host>

1472 is not arbitrary. Add 8 bytes of ICMP header and 20 bytes of IPv4 header and you get exactly 1500: the standard Ethernet MTU. So payload + 28 = the packet size you are really testing.

Three outcomes, three meanings:

Why silence is the whole problem

When a router receives a packet larger than the next link allows and the Don't Fragment bit is set, it is supposed to drop the packet and return an ICMP "fragmentation needed" message (type 3, code 4) naming the size it can handle. Your machine shrinks its packets and everything continues. That mechanism is path MTU discovery, and it works invisibly thousands of times a day.

It breaks when a firewall somewhere blocks ICMP wholesale: usually because "ICMP is a security risk" was applied with a broad brush. The oversized packet still gets dropped. The message explaining why never arrives. Your machine has no idea anything is wrong, so it keeps sending the same oversized packets forever.

That is why the connection establishes. The TCP handshake is tiny. Authentication is tiny. The session only dies when real data starts flowing, which is why it looks like the application's fault.

Find the actual limit

Narrow it by halving. Drop to 1400, and if that works try 1450; if it fails try 1300. A handful of probes gets you to the edge:

ping -M do -s 1472 host   → timeout
ping -M do -s 1400 host   → timeout
ping -M do -s 1300 host   → reply      ← somewhere between 1300 and 1400
ping -M do -s 1350 host   → reply
ping -M do -s 1372 host   → reply      ← 1372 + 28 = 1400 byte path MTU

Common answers and what they suggest: 1500 plain Ethernet; 1492 PPPoE, so a DSL line somewhere; 1460 or 1400 a GRE or IPsec tunnel; 1280 the IPv6 minimum, and a frequent VPN default.

Fixing it

If you control the firewall: stop blocking ICMP type 3 code 4

This is the real fix, and it is not a security compromise. You are not permitting pings: you are permitting the error message that makes the internet's size negotiation work. Blocking it does not harden anything; it just breaks large transfers in a way nobody can diagnose.

If you do not: clamp the MSS

MSS clamping rewrites the maximum segment size in the TCP handshake, so both ends agree on something small enough before any data moves. No ICMP required. On a Linux router:

iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN \
         -j TCPMSS --clamp-mss-to-pmtu

Most VPN appliances and routers expose this as "TCP MSS clamping" or "MSS adjust". The value is the path MTU minus 40: 20 bytes of IP header and 20 of TCP.

Clamping only fixes TCP. It rewrites TCP handshakes and does nothing whatsoever for UDP, so if the broken thing is a UDP-based VPN, DNS over a tunnel, or QUIC, you must lower the interface MTU instead.

As a local workaround

Lowering the MTU on your own interface fixes your machine only, and is a reasonable stopgap while someone with access to the middle of the path does it properly:

Linux     sudo ip link set dev eth0 mtu 1400
macOS     sudo ifconfig en0 mtu 1400

What not to conclude

A clean ping proves nothing here. Default pings are 64 bytes, far below any MTU on any path, so they sail through a black hole untouched. "But ping works fine" is the single most common reason this goes undiagnosed for days.

Equally, do not read it as packet loss. Loss is random and proportional; this is deterministic and size-dependent. Every packet under the limit arrives, every packet over it disappears, and it will behave identically tomorrow.

Kodura Network Tools runs the probe sequence above from your iPhone or iPad and reports the path MTU directly, rather than leaving you to bisect by hand. It also runs ping, traceroute, DNS lookups and port checks against the same target, so you can rule out the simple explanations first, which is the order this problem needs.

Download on the App Store

Why this one is not a web tool

There is no "test my MTU" button on this page, and there should not be. A browser cannot set the Don't Fragment bit or send ICMP at all, and a test run from our server would measure the path between our data centre and the target: not the path that is actually failing for you. The measurement is only meaningful from the machine with the problem.

The same limit applies to traceroute, for the same reason, which is covered in what the asterisks in a traceroute actually mean. Where a check genuinely does work in a browser: DNS, certificates, subnet arithmetic: we put it in the free tools instead.