The classic VPN complaint: “I can ping it, SSH connects, small pages load — but big downloads, file shares and some websites just freeze halfway.” Nothing is down. A packet somewhere is too big for a link in the path, the router that should say so is being silenced, and the sender keeps resending a packet that can never fit. This is the MTU black hole.
Every link has a Maximum Transmission Unit — the largest frame it will carry (1500 bytes on plain Ethernet, less inside a tunnel: PPPoE 1492, IPsec/GRE/WireGuard lower still). When a host sends a full-size packet with the Don’t Fragment bit set and it reaches a link too small for it, the router is supposed to drop it and send back an ICMP “fragmentation needed” message telling the sender to use a smaller packet. That feedback loop is Path MTU Discovery.
Block that ICMP — with a lazy “drop all ICMP” firewall rule, or a provider who filters it — and the loop goes silent. The sender never learns, keeps retransmitting the same too-big packet, and the transfer stalls forever while small packets pass fine. It is called a black hole because the packets vanish with no error anywhere the user can see.
01
A small ping crosses the narrow tunnel link fine. The big packet is too large, the “too big” message is blocked, and the sender keeps resending it into the void.
Why does SSH connect then hang? The handshake is small packets — it completes. The moment the server sends a big burst (a directory listing, the TLS certificate, a file), those full-size segments hit the narrow link and vanish. So the session opens and then freezes on the first large response, which feels bizarre until you know the shape of this bug.
02
A tunnel lowers the path MTU; the Don’t-Fragment bit forbids the router from splitting the packet; a blocked ICMP removes the only way the sender would find out.
| Ingredient | Role in the black hole |
|---|---|
| A tunnel in the path | IPsec/GRE/WireGuard/PPPoE add headers, so the usable MTU inside is below 1500 — often 1400 or less. |
| Don’t Fragment set | Modern TCP sets DF and relies on PMTUD, so the router may not fragment — it must signal instead. |
| ICMP type 3 code 4 blocked | “Fragmentation needed” is the signal. A blanket ICMP drop silences it — the sender never shrinks. |
| Large payloads only | Handshakes and pings are small and pass; bulk transfer and TLS certs are full-size and die. Hence “works then hangs.” |
03
Every tell points at size: it is fine until something big crosses the path.
| What you see | What it tells you |
|---|---|
| Ping fine, SSH connects then freezes on output | Small passes, first big burst dies — the signature. |
| Some websites load headers then stall | Big responses (images, TLS cert chains) hit the MTU wall. |
| Only VPN / tunnel users affected | The low-MTU link is inside the tunnel. |
| A big ping with DF fails; a small one works | Direct proof of the breaking size (see the field check). |
04
Two fixes, and you usually apply both: let the ICMP through, and clamp TCP so it never sends a segment too big for the tunnel in the first place.
The robust fix on a tunnel edge is MSS clamping: the router rewrites the TCP Maximum Segment Size in the handshake down to what the tunnel can carry, so both ends agree to send segments that always fit. It does not rely on ICMP getting through at all, which is why it is the real fix rather than a workaround.
# rewrite MSS on TCP SYNs crossing the tunnel to fit the path automatically /ip firewall mangle add chain=forward protocol=tcp tcp-flags=syn action=change-mss new-mss=clamp-to-pmtu \ out-interface=wg-tunnel passthrough=yes # and set the tunnel interface MTU/MRU correctly so PMTUD has the right number
interface Tunnel0
ip tcp adjust-mss 1360
! do NOT blanket-drop ICMP — permit unreachables (type 3) inbound
ip access-list extended WAN-IN
permit icmp any any packet-too-big
permit icmp any any unreachableBlocking ICMP wholesale “for security” is the single most common cause of an MTU black hole. ICMP type 3 code 4 (fragmentation needed) is not an attack — it is load-bearing plumbing for the modern internet. Permit the unreachables even if you rate-limit or drop echo. The rest of this series is full of “the safe-looking default that breaks everything,” and this is the layer-3 one.
05
Binary-search the breaking packet size with DF set. The size where ping stops working is your path MTU.
# Linux/mac: ping with Don-t-Fragment, sweeping the payload size ping -M do -s 1472 SERVER # 1472+28 = 1500; fails if path MTU < 1500 ping -M do -s 1372 SERVER # 1372+28 = 1400; works -> path MTU is ~1400 # Windows: ping -f -l 1472 SERVER # confirm the ICMP is being blocked rather than sent sudo tcpdump -ni any 'icmp[icmptype] == 3' # frag-needed arriving? or silence?
If a small ping works and a big one with DF fails, and you see no “fragmentation needed” ICMP coming back, you have a black hole. Clamp MSS on the tunnel and the transfers unstick immediately — then fix the ICMP filtering so PMTUD works for everything else too.
Takeaways
The MTU black hole is invisible to a ping and obvious once you measure it. I find the breaking packet size, fix Path MTU Discovery, and clamp MSS on the tunnel so transfers stop freezing.
Book a Discovery Call →