What MTU Should You Use? Fix HTTPS Hangs from MTU Black Holes

Blog / Troubleshooting

What MTU Should You Use? Fix HTTPS Hangs from MTU Black Holes

The right MTU depends on the narrowest segment between your machine and the destination. Ordinary Ethernet and Wi-Fi LANs use 1500, PPPoE dial-up links usually use 1492, and every layer of VPN, tunnel, or container networking on top subtracts its encapsulation overhead. Most of the time you do not need to change the MTU by hand. You only need to touch it when you see the "small requests work, big packets hang" symptom and the bisection method below confirms that the path MTU is smaller than your NIC's MTU.

What symptoms point to an MTU black hole?

MTU problems rarely look like a total outage. More often things work halfway:

  • ping works, DNS resolves, and the TCP three-way handshake completes, but HTTPS stalls in the TLS handshake and times out after a while.
  • A page's skeleton loads, but images or large JS files spin forever. Some sites work and others do not.
  • git clone or npm install stops partway with no error.
  • When calling an AI API, short requests return normally, but requests with a long context or file attachments never get a response.
  • SSH logs in fine, but the terminal freezes when you cat a large file or run ls -la on a big directory.

What these have in common: small packets get through, full-size packets do not, and nobody tells the sender the packet was too big.

Why do big packets disappear silently?

Every link has a maximum IP packet size it can carry, the MTU. The smallest MTU along a path is the path MTU (PMTU).

Normally the sender sets the DF (Don't Fragment) bit on TCP packets. When some hop finds a packet too big, it drops it and sends back an ICMP message: "Fragmentation Needed" (type 3, code 4) for IPv4, or "Packet Too Big" for IPv6. The sender then shrinks its packets and retransmits. This process is Path MTU Discovery (PMTUD).

The trouble starts when a firewall, cloud security group, or ISP device along the way drops those ICMP messages. The sender never gets the hint, keeps retransmitting the same-size packet, and it keeps getting dropped. That is an "MTU black hole."

TLS handshakes are a classic victim because the client's ClientHello is usually small and goes out fine, while the server's ServerHello plus certificate chain is often several KB and gets cut into full-size TCP segments that run straight into the black hole. With curl -v, you see it stop right after TLSv1.3 (OUT), TLS handshake, Client hello with nothing after. Also, newer browsers and some TLS libraries enable post-quantum key exchange, so the ClientHello itself can exceed one packet and the upstream direction can be affected too.

If you want to sort "can't connect" problems by layer first, see Claude Code connection timeouts and errors: a four-layer network checklist. MTU falls into the "TCP works, TLS doesn't" category there.

What should the MTU be in common setups?

In the table below, MSS means the maximum TCP payload per segment over IPv4: the MTU minus a 20-byte IP header and a 20-byte TCP header (subtract 60 for IPv6).

ScenarioTypical MTUIPv4 MSSNotes
Ordinary Ethernet, Wi-Fi LAN15001460Default, usually leave it alone; if the upstream is PPPoE, the outbound path is still 1492
PPPoE interface (bridged modem, router dial-up)14921452PPPoE header takes 8 bytes
GRE tunnel14761436GRE encapsulation takes 24 bytes
WireGuard (wg-quick default)14201380Leaves headroom for an outer IPv6 header
VXLAN and other overlay container networks14501410Encapsulation takes 50 bytes
IPv6 minimum1280n/aNo IPv6 link may go below this

These numbers stack. Say you run WireGuard over a PPPoE line, and Docker's overlay network inside WireGuard: each layer must subtract its overhead from the layer below. By the third layer, if any one of them is still configured for 1500, you get a black hole.

How do you measure your path MTU? Commands for three platforms

The idea is to send pings with the DF bit set, adjust the payload size step by step, find the largest size that gets through, and add 28 bytes (20 IPv4 header + 8 ICMP header) to get the path MTU. For IPv6, add 48.

Step 1: pick a target that answers ping

Many websites' servers do not answer ICMP, so every size will time out and you learn nothing. First ping with the default size to confirm the target replies. A public DNS address works, or the API server where you actually see the problem (if it answers ping). If you are fuzzy on how ICMP and TCP probes differ, read Ping fails but the site opens? ICMP ping vs tcping and how to use each first.

Step 2: test 1472 to see if a full 1500 works

OSCommandTypical output when the packet is too big
Windowsping -f -l 1472 1.1.1.1Packet needs to be fragmented but DF set. (shown in Chinese on Chinese-language Windows)
Linuxping -M do -s 1472 -c 3 1.1.1.1Frag needed and DF set (mtu = 1492) or message too long
macOSping -D -s 1472 -c 3 1.1.1.1sendto: Message too long or a plain timeout

-f (Windows), -M do (Linux), and -D (macOS) all set the DF bit; -l and -s set the ICMP payload size.

If 1472 gets through, the path to this target supports 1500 and MTU is most likely not your problem. You can skip to the last section.

Step 3: if it fails, bisect

Bisect between 1200 and 1472. For example:

  1. Test 1336. It works, so the limit is between 1336 and 1472.
  2. Test 1404. It fails, so the limit is between 1336 and 1404.
  3. Test 1370. It works; then test 1387, and so on.
  4. Continue until the bounds differ by 1 byte. Take the largest size N that works; path MTU = N + 28.

One easy misreading to avoid: if an oversized ping produces neither an error nor a reply, just a timeout, that is itself evidence of a black hole. It means a middle device is dropping the packet without sending ICMP back.

On Linux, you can just use tracepath

tracepath -n api.example.com
# The output ends with something like: Resume: pmtu 1420 hops 12 back 12

tracepath reports pmtu changes hop by hop, so you can see which hop makes it shrink. For how to read per-hop output, see How to read traceroute and mtr results.

Confirm with curl that it is stuck in TLS

curl -v --max-time 15 -o /dev/null https://api.example.com/

If it times out right after Client hello, and everything works immediately once you temporarily lower the local MTU, you can be fairly confident it is an MTU black hole.

Once you have the number, how do you change the MTU?

Check the current MTU first

# Windows (admin PowerShell or CMD)
netsh interface ipv4 show subinterfaces

# Linux
ip link show

# macOS
networksetup -getMTU en0

Lower it temporarily to verify

# Windows: use the interface name from the previous step; store=active is lost on reboot
netsh interface ipv4 set subinterface "Ethernet" mtu=1400 store=active

# Linux: lost on reboot
sudo ip link set dev eth0 mtu 1400

# macOS
sudo networksetup -setMTU en0 1400

First try a value a bit below what you measured (if you measured 1420, set 1400) to check that the problem goes away. Then set it to the measured value and make it persistent: on Windows use store=persistent; on Linux put it in your NetworkManager, netplan, or systemd-networkd configuration.

Tunnels and containers have their own settings

  • WireGuard: put a value like MTU = 1380 under [Interface]. Compute it as the outer path MTU minus 60 (outer IPv4) or 80 (outer IPv6).
  • Docker: set "mtu": 1400 in /etc/docker/daemon.json and restart Docker. When the host goes through a VPN, the container's default of 1500 is a common source of black holes.
  • Kubernetes: set it in the CNI plugin's configuration. The field differs between plugins, so follow that plugin's documentation.

What is MSS clamping, and when do you use it?

Changing the MTU only affects packets sent from that machine. If you run a router, gateway, or VPN server with many devices behind it, changing each one is impractical. That is where MSS clamping comes in: when a TCP handshake SYN packet passes through, you rewrite the MSS it advertises to a smaller value, so both ends never send segments larger than the path MTU from the start. It does not depend on ICMP, so it works around dropped PMTUD messages.

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

# nftables
nft add rule inet filter forward tcp flags syn tcp option maxseg size set rt mtu

--clamp-mss-to-pmtu computes the value automatically from the outgoing interface's MTU. If that MTU is configured correctly but there is a narrower link further along, you need a fixed value such as --set-mss 1360. Many home routers enable this by default in PPPoE mode, while self-built VPN gateways are easy to misconfigure.

If you only have Linux clients and cannot change the network devices, you can enable TCP-level MTU probing as a fallback:

sudo sysctl -w net.ipv4.tcp_mtu_probing=1

It automatically lowers the segment size once it detects a black hole. The cost is that the first stall has to wait out one retransmission timeout before it recovers. Note that it only applies to TCP, not to QUIC/UDP.

When should you not change the MTU?

  • 1472 gets through. If the path supports 1500, lowering the MTU only raises header overhead as a share of each packet. The problem is elsewhere.
  • Every size times out. The target probably does not answer ICMP, or is simply unreachable. Check DNS and routing first. For resolution-level problems, start with the Developer network self-check list (2026 edition).
  • Streaming output cuts off after a fixed duration. If it always drops at about the same number of seconds, that looks more like an idle timeout on a proxy or load balancer and has nothing to do with packet size.
  • Only IPv6 is affected. First check whether your IPv6 egress and IPv4 egress take different paths; see IPv6 proxy not taking effect: why dual-stack egress differs and how to debug it. Also, never set an IPv6 MTU below 1280.
  • You changed the NIC MTU but traffic goes through proxy software. Some proxies work through a TUN virtual adapter. The MTU you need to change is on that virtual adapter or in the proxy's own settings, not on the physical NIC.

Cross-check with cdnping

After making changes, open the cdnping online speed test and check whether the "first connection" for each AI API completes normally. That metric includes DNS and TLS handshake, so an MTU black hole usually makes it time out or grow noticeably, while the "round trip" metric is measured after connection reuse and is less affected. The two numbers are explained in detail in AI API latency breakdown: connection setup, gateway round trip, and time to first token.

If only one provider fails to open, check API status to see whether its official endpoint looks healthy from cdnping's edge probes, which rules out an outage on their side. If you use a VPN or split routing, you can also use IP and environment check to confirm your actual egress and routing results and work out which path your large packets take.

One-page checklist

  1. Is the symptom "small requests work, big responses hang," and does curl -v stop at the TLS handshake?
  2. Test 1472 with a DF ping; if it fails, bisect. Path MTU = largest size that works + 28.
  3. Count how many encapsulation layers are stacked on the path: PPPoE, VPN, tunnels, container networking.
  4. Temporarily lower the MTU on the local machine or virtual adapter; make it persistent only after the problem disappears.
  5. When managing a gateway, use MSS clamping rather than having every device change its own MTU.
  6. If 1472 gets through, or the problem has nothing to do with packet size, leave the MTU alone.

Related articles

Keep reading