Small packets pass, large ones vanish: the classic MTU black hole. Ping tests pass, SSH works, then HTTPS handshokes stall and big uploads hang. Test MTU path-wise; it's a one-command diagnosis.
WireGuard/VXLAN/VPN add bytes: inner 1500 MTU + overhead exceeds the real 1500 path. Small packets fit; full-size ones need fragmentation that firewalls often drop (PMTUD black hole).
Path MTU discovery relies on ICMP type 3 code 4 messages; aggressive firewall rules silently drop them, so senders never learn to shrink packets and big flows stall.
ping -M do -s 1472 -c 3 <host> # 1472+28=1500; decrease the payload until it passes: that's your real path MTU minus 28
# wireguard example: ip link set dev wg0 mtu 1380 ; docker: docker network create --opt com.docker.network.driver.mtu=1400 <net>
# firewall: allow icmp type 3 code 4 — restores path-MTU discovery for everyone on that segment
curl -o /dev/null -w '%{size_download} bytes %{time_total}s\n' https://speed.cloudflare.com/__down?bytes=10000000
Common values: WireGuard over IPv4 ≈ 1420, VXLAN overlays 1450-1500 depending on encap, cloud VPNs vary — discover, don't guess. 'Everything works except TLS handshakes from some clients' inside tunnels is the strongest MTU tell there is.
Packets under the path MTU traverse fine; full-size packets need fragmentation or PMTUD. When ICMP feedback is blocked, the sender retransmits into a black hole and only the large flows die.
Use DF-bit ping sweeps (-M do, decreasing sizes) toward the affected destination — the largest passing payload + 28 bytes is the path MTU. Set your tunnel/overlay below it.
Our most-documented failures, packaged as ready-to-ship starter kits: Docker, Kubernetes, and Terraform.
Browse the template store →One-time. Yours to modify. Instant download from the NinjaOps template store.