Skip to main content
TACUNS
Module 2 of 5
40% complete
Module 2

MTU & MSS Mismatches — 'Works in the Office, Broken Over VPN'

The Symptom Pattern That Points Directly at MTU

  • "Website loads the homepage but hangs on login — the POST never completes"
  • "Large file downloads fail at exactly the same point every time"
  • "SSH connects and I can authenticate, but the terminal freezes when I paste more than a few lines"
  • "Works fine on the office network, broken as soon as users connect to VPN"
  • "HTTPS to internal servers works, HTTPS to external sites hangs"

Why MTU Problems Are Invisible to Ping

Standard ping uses 64-byte packets by default. An MTU problem only appears with large packets. A network can look completely healthy in all monitoring — ping succeeds, traceroute completes, BGP is stable — while silently dropping every TCP packet above a certain size. This is why MTU issues go undiagnosed for days while engineers chase routing problems that do not exist.

The MTU and MSS Relationship — What Actually Breaks

Maximum Transmission Unit is the largest frame a physical link can carry. Maximum Segment Size is the TCP-layer value that limits how large a single TCP data segment can be. They are related but set independently, and the mismatch between them is where production failures hide.

LayerValueWhere It Is SetWhat Breaks When Wrong
Layer 2 (Ethernet)MTU: 1500 bytesNetwork interface configuration, switch portFragmentation required — or if DF bit set, packets silently dropped
Layer 3 (IP)DF bit (Don't Fragment)Set by TCP stack or applicationICMP 'fragmentation needed' must be returned — blocked firewalls cause PMTUD to fail
Layer 4 (TCP)MSS: typically 1460 bytes (1500 - 20 IP - 20 TCP)Negotiated in SYN/SYN-ACK handshakeIf MSS is too high for the path, large segments get dropped silently
VPN TunnelOverhead: 50-100 bytes depending on protocolVPN configurationEffective MTU drops — packets that fit the Ethernet link no longer fit the tunnel

Why VPN Makes This Worse

A VPN tunnel adds overhead — IPsec ESP headers, GRE encapsulation, or TLS wrapping depending on the VPN type. A packet that is exactly 1500 bytes on the LAN side will be 1548-1600 bytes after VPN encapsulation. That packet no longer fits the 1500-byte MTU of the internet link — and if the original IP header had the DF bit set, the packet gets dropped with no notification reaching the application.

Path MTU Discovery depends on ICMP Type 3 Code 4 — "Fragmentation Needed" — being delivered back to the sender. Most enterprise firewalls and many ISP devices block ICMP. When ICMP is blocked, PMTUD silently fails and large packets are dropped forever. The connection never recovers.

The Debug Sequence — Confirming MTU Is the Cause

Step 1: The Definitive Test

cisco-ios
! The single most important test for MTU diagnosis:
! Send a large packet with DF bit set — if this fails but small ping succeeds, MTU is the problem

! From a Windows client:
ping <destination-ip> -f -l 1472
! -f = set Don't Fragment bit
! -l 1472 = 1472 bytes payload + 28 bytes IP/ICMP header = 1500 total
! If this succeeds: MTU is fine on this path
! If this fails: MTU problem confirmed

! Try smaller sizes to find the exact MTU ceiling:
ping <destination-ip> -f -l 1400
ping <destination-ip> -f -l 1300
ping <destination-ip> -f -l 1200
! The largest size that succeeds tells you the effective MTU

! From a Linux/macOS client:
ping -M do -s 1472 <destination-ip>
! -M do = set DF bit
! -s 1472 = payload size

! From Cisco IOS router:
ping <destination-ip> size 1500 df-bit repeat 5
! This is the router-originated version — tests the path from the router itself

Step 2: Check Interface MTU Configuration

cisco-ios
! Check current MTU on all interfaces
show interfaces | include MTU|line protocol

! Check specific interface
show interface GigabitEthernet0/0 | include MTU

! Check MTU on subinterfaces (common mismatch point)
show interfaces | include Ethernet|MTU

! For tunnel interfaces — where the mismatch usually lives:
show interface Tunnel0
! Look for: MTU 1476 bytes (or whatever value is set)
! Compare this to physical interface MTU of 1500
! The tunnel MTU should be physical MTU minus tunnel overhead

Step 3: Trace Where Packets Are Being Dropped

cisco-ios
! Check if ICMP unreachable messages are being generated
! (confirms fragmentation is happening or DF-drop is happening)
show ip interface | include Unreachables

! Debug IP ICMP to see fragmentation-needed messages:
debug ip icmp
! WARNING: Use on low-traffic interfaces only — very verbose
! Look for: "ICMP: dst (x.x.x.x) frag. needed and DF set, sending"
! This confirms the router is generating PMTUD responses

! Check if ICMP unreachables are disabled (blocks PMTUD response)
show running-config | include no ip unreachables

! If you see "no ip unreachables" on the interface — this blocks PMTUD
! Re-enable with: ip unreachables (on the outbound interface)

! Check MTU on the path end-to-end using traceroute with probe size
traceroute <destination> size 1500 df-bit

Step 4: Check MSS in TCP Sessions

cisco-ios
! On Cisco router — check tcp adjust-mss configuration
show running-config | include tcp adjust-mss

! Check active TCP sessions MSS negotiation:
! Capture packets and look at SYN and SYN-ACK for MSS option
! In Wireshark: tcp.flags.syn==1 → look at TCP Options → MSS value

! On PAN-OS — check MSS clamping in interface config
show interface ethernet1/1
! Look for: "MSS Adjustment" in the output

! On Linux — check interface MTU
ip link show
! Look for: mtu 1500 or whatever the value is
! Check effective MSS for a connection:
ss -ti dst <remote-ip>
! Shows: rcvmss, advmss, pmtu values

Root Cause Patterns and Fixes

Root CauseWhere to Find ItFix
VPN tunnel overhead not accounted forTunnel interface MTU > physical MTU minus overheadSet tunnel interface MTU to 1400-1420 for IPsec, 1476 for GRE
ICMP unreachables disabled — PMTUD brokenshow running | include no ip unreachables on WAN interfaceip unreachables on the WAN-facing interface, AND allow ICMP type 3 through firewall
MSS not clamped on tunnel or WAN interfaceTCP sessions negotiating MSS of 1460 but path cannot carry itip tcp adjust-mss 1452 on the WAN or tunnel interface (both directions)
Jumbo frames misconfigurationSome switches set to 9000 MTU, others at 1500 — inconsistent across pathStandardize MTU across all devices in the path, or explicitly set DF-bit handling
Docker/container networkingContainer veth interfaces with lower MTU than hostSet MTU in docker daemon.json to match the host path MTU

The MSS Clamp — Preferred Fix for Most Environments

cisco-ios
! Apply MSS clamping on the interface where packets exit to the problem path
! This modifies the MSS value in TCP SYN packets to prevent oversized segments

! On Cisco IOS — apply to the WAN or tunnel interface:
interface GigabitEthernet0/0
  ip tcp adjust-mss 1452
! This tells the router to rewrite any TCP MSS value above 1452 to 1452
! 1452 = 1500 (Ethernet) - 20 (IP) - 20 (TCP) - 8 (overhead buffer)

! For IPsec VPN tunnels — use a lower value:
interface Tunnel0
  ip tcp adjust-mss 1360
! IPsec ESP overhead: ~50-60 bytes
! 1500 - 60 (IPsec) - 20 (IP) - 20 (TCP) = approximately 1360-1400

! Verify the clamping is working:
! Run a packet capture on the tunnel interface
! Check SYN packets outbound — MSS should now show 1452 (or your set value)
! NOT the original 1460 that the client negotiated

! On PAN-OS — MSS adjustment in Network > Interfaces > Advanced tab
! Or via CLI:
set network interface ethernet ethernet1/1 adjust-tcp-mss enable yes
set network interface ethernet ethernet1/1 adjust-tcp-mss ipv4-mss-adjustment 40

Why 1452 and Not 1460

Standard Ethernet MTU is 1500. IP header is 20 bytes. TCP header is 20 bytes. That leaves 1460 for TCP payload — which is the standard MSS. But VPN tunnels, MPLS labels, and other encapsulations add overhead outside the original IP packet. Setting MSS to 1452 gives an 8-byte safety buffer that prevents fragmentation on most real-world paths. For IPsec tunnels, go lower — 1360 is safe for most configurations. If in doubt, start at 1350 and increase until you find the breaking point.

The VPN-Specific Scenario — Full Debug Flow

The most common MTU complaint: everything works on the corporate LAN, everything breaks when connected to VPN. Here is the exact sequence that finds the cause every time.

cisco-ios
! Step 1: Confirm the path works without VPN
! From client machine ON the LAN (not VPN):
ping <problem-destination> -f -l 1472
! Must succeed — establishes baseline

! Step 2: Connect to VPN, repeat the same test
ping <problem-destination> -f -l 1472
! If this fails: MTU problem is in the VPN path

! Step 3: Find the working MTU over VPN
ping <problem-destination> -f -l 1300
ping <problem-destination> -f -l 1350
ping <problem-destination> -f -l 1400
! Find the largest size that succeeds

! Step 4: Calculate the overhead
! If 1400 succeeds but 1450 fails:
! Effective MTU = 1400 + 28 (ICMP overhead) = 1428
! Tunnel overhead = 1500 - 1428 = 72 bytes
! That is consistent with IPsec ESP in tunnel mode

! Step 5: Fix — apply MSS clamping on the VPN gateway interface
! The VPN gateway router or firewall:
interface Tunnel0
  ip tcp adjust-mss 1360
! This prevents TCP from negotiating segments too large for the tunnel

! Step 6: Verify fix
! Run a file download or HTTPS session that was previously failing
! If it now completes — MTU was the cause

The reason "restart fixed it" sometimes works for MTU issues: a TCP connection that gets stuck negotiating with the original (too-large) MSS will stay stuck. After restart, if PMTUD has figured out the correct path MTU (or if the MSS clamp is now in place), new connections negotiate the correct MSS from the start. The connection was not fixed — it was replaced with a new connection that does not have the problem.