The most common production problem with GRE tunnels is not configuration. It is MTU. Pings work. Small TCP connections work. Then a user opens a webpage and it loads halfway. Or a database client throws timeouts. Or a backup job that runs over the tunnel hangs at exactly 95 percent. The symptom is "the tunnel is up but big things break." The cause is almost always that the inner packet is too large to fit through the path once GRE encapsulation, IPsec encryption, and underlay headers have been added, and somewhere along the way packets are being silently dropped instead of cleanly fragmented.
This article walks through the math, the two-line IOS XE fix that prevents most of the pain, and the debugging recipe for diagnosing MTU problems when they have already started biting. It is part of the PingLabz GRE Tunnels guide.
The Overhead Math
Every encapsulation adds bytes. GRE is small but IPsec is not. The standard 1500-byte Ethernet underlay you almost certainly have for the tunnel source interface eats up fast:
| Layer | Bytes | Cumulative remaining for inner payload |
|---|---|---|
| Ethernet underlay MTU | 1500 | 1500 |
| Outer IPv4 header | -20 | 1480 |
| GRE header | -4 | 1476 |
| IPsec ESP header + IV (AES) | -16 | 1460 |
| IPsec ESP padding (worst case) | -15 | 1445 |
| IPsec ESP trailer | -2 | 1443 |
| IPsec ICV (SHA-256) | -16 | 1427 |
| NAT-T UDP wrapper (if NAT in path) | -8 | 1419 |
That is why the canonical "set ip mtu 1400 on the tunnel" advice exists. 1400 is a round number that leaves headroom for the worst-case IPsec scenario plus a few bytes of margin for things that show up in production but not in lab (jumbo-frame mismatches at carrier handoffs, unexpected VLAN tags, MPLS labels). If you are running plain GRE without IPsec and you know the underlay path is consistent end-to-end, you can use 1476 (1500 minus the GRE+outer-IP overhead). Most of the time you will eventually add IPsec, and going back to retune MTU later is more painful than starting at 1400.
The Two-Line Fix
On every GRE tunnel interface in production:
interface Tunnel0
ip mtu 1400
ip tcp adjust-mss 1360Each line solves a different aspect of the problem.
ip mtu 1400 tells the router that the maximum size of an IP packet allowed onto the tunnel interface (after the inner-IP processing but before GRE encapsulation) is 1400 bytes. Anything larger gets fragmented into 1400-byte pieces before GRE wraps it. After GRE adds 24 bytes and IPsec adds up to 76 bytes, the resulting packet still fits in the underlay's 1500-byte MTU. No fragmentation needed at the underlay level.
ip tcp adjust-mss 1360 rewrites the MSS (Maximum Segment Size) value inside TCP SYN packets passing through the router. TCP endpoints negotiate MSS during the three-way handshake based on what they think the path MTU is. When the endpoints are unaware of the GRE+IPsec overhead, they advertise an MSS of 1460 (1500-byte path MTU minus 20 IP minus 20 TCP), and every full-size segment ends up being 1460 + 20 + 20 = 1500 bytes of inner IP. That is too big for the tunnel.
By rewriting MSS to 1360 (1400 inner-MTU minus 20 IP minus 20 TCP), the router forces the endpoints to negotiate a segment size that fits without ever needing fragmentation. This is the elegant fix because it eliminates the problem at the source rather than coping with it downstream.
Both ends of the tunnel should have these commands. The MSS clamping happens on each TCP SYN as it crosses the tunnel, regardless of direction.
Why Cannot the Network Just Fragment?
In theory, IP fragmentation handles oversized packets cleanly. In practice it does not work in 2026, for three reasons.
- Don't-Fragment bit is set on most TCP traffic. Modern TCP stacks set DF=1 by default for Path MTU Discovery (PMTUD). When a router needs to fragment a DF=1 packet, it instead drops it and sends an ICMP Type 3 Code 4 ("fragmentation needed") message back to the sender, telling it to lower its packet size. PMTUD relies on that ICMP message getting back.
- ICMP is filtered. Many enterprise firewalls, ISP middleboxes, and home routers drop ICMP. The "fragmentation needed" message never returns to the sender. The TCP endpoint waits, retransmits the same oversized packet, gets dropped again, and the connection stalls. This is the classic "PMTUD black hole" failure mode.
- Fragmentation is expensive. Even when fragmentation works, the receiving router has to reassemble fragments before processing, which costs CPU and memory. On heavily-loaded routers it is a significant performance hit. On linecard ASICs that punt fragments to the CPU, it can collapse throughput.
That is why MSS clamping is preferred over relying on PMTUD. MSS clamping makes the problem go away at the TCP-handshake level. PMTUD is the fallback for traffic that is not TCP, like UDP-based applications, where you cannot rewrite MSS because there is no MSS to rewrite.
Symptoms of MTU Misconfiguration
The classic patterns engineers report:
- "Pings work but the website does not load." Default ICMP echo is 84 bytes (with the headers); they fit in any path. Real traffic uses full-size segments and stalls when fragmentation black-holes them.
- "Some sites work, others do not." Sites with PMTUD-friendly paths (small replies, ICMP allowed) work. Sites with large replies and ICMP filtering do not.
- "It works sometimes." Different MTUs are negotiated on different connection retries. The connection that happens to negotiate a small MSS works.
- "Database queries hang at exactly 95 percent." The backup or query was sending small packets through the connection and they all flowed; the final large response (the table contents, the file body) hits the MTU wall.
- "VPN works for HTTP but not for email or file transfers." HTTP page loads use small request headers and stream responses; bigger payloads tip over the MTU threshold.
Diagnosing MTU Problems
The single most useful diagnostic is a sized ping with the Don't-Fragment bit set. From the router that originates the tunnel:
R1# ping 10.0.0.2 size 1400 df-bit
Type escape sequence to abort.
Sending 5, 1400-byte ICMP Echos to 10.0.0.2, timeout is 2 seconds:
Packet sent with the DF bit set
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 5/5/8 ms
R1# ping 10.0.0.2 size 1500 df-bit
Type escape sequence to abort.
Sending 5, 1500-byte ICMP Echos to 10.0.0.2, timeout is 2 seconds:
Packet sent with the DF bit set
M.M.M
Success rate is 0 percent (0/5)M in the output means "could not fragment" - the router on the path tried to forward a packet larger than the egress MTU but the DF bit prevented it. That is the canonical signature of an MTU problem.
Walk the size up and down to find exactly where the limit is:
R1# ping 10.0.0.2 size 1450 df-bit ! 1450 fails -> below 1450 the path is OK
R1# ping 10.0.0.2 size 1400 df-bit ! 1400 succeeds -> safe for IP MTU
R1# ping 10.0.0.2 size 1420 df-bit ! finer grainThe largest size that succeeds with df-bit is your effective path MTU through the tunnel. Set ip mtu to that value or below.
From a Linux endpoint, the same idea with ping:
$ ping -M do -s 1400 192.168.2.10
PING 192.168.2.10 (192.168.2.10) 1400(1428) bytes of data.
1408 bytes from 192.168.2.10: icmp_seq=1 ttl=63 time=5.01 ms
$ ping -M do -s 1500 192.168.2.10
PING 192.168.2.10 (192.168.2.10) 1500(1528) bytes of data.
ping: local error: message too long, mtu=1500
ping: local error: message too long, mtu=1500Linux's -M do is "don't fragment, fail if too big," equivalent to df-bit on Cisco.
Useful Show Commands
R1# show interface Tunnel0 | include MTU
MTU 17916 bytes, ...
Tunnel transport MTU 1476 bytesThe Cisco "MTU 17916" is the platform-supported maximum size; ignore it. The "Tunnel transport MTU 1476" is the IOS XE-calculated maximum after GRE+IP overhead. You override this with ip mtu 1400.
R1# show interface Tunnel0 | include ip mtu|adjust
IP MTU 1400 bytes
IP TCP MSS 1360 bytesIf you do not see those two lines, the commands are not applied. Re-add them.
IPv6 Considerations
IPv6 changes the MTU story in two ways. First, IPv6 routers do not fragment in transit at all - the source must do PMTUD, and an oversized packet anywhere in the path is dropped with an ICMPv6 "Packet Too Big" reply. Second, the minimum IPv6 MTU is 1280 bytes; if any link in the path is below that, IPv6 will not work.
For GRE tunnels carrying IPv6:
interface Tunnel0
ipv6 mtu 1400
ipv6 tcp adjust-mss 1360Same logic, IPv6 versions of the commands. The 1400 inner-MTU value is conservative enough to handle GRE plus IPsec plus the IPv6-vs-IPv4 outer-header difference.
When You Cannot Avoid Fragmentation
If endpoints generate UDP traffic with DF=1 set and you cannot rewrite the application, occasional fragmentation will happen. On Cisco IOS XE you can pre-fragment at the tunnel ingress so the IPsec layer never has to:
crypto ipsec fragmentation before-encryptionThis is a global command. It tells the router to fragment large packets at the GRE encapsulation layer before they hit IPsec, which avoids the more-expensive after-encryption fragmentation path. It does not solve the underlying MTU problem - the inner IP packet is still being fragmented - but it keeps the dataplane fast path engaged.
Summary
Two lines of config eliminate 90 percent of GRE tunnel MTU pain on Cisco IOS XE: ip mtu 1400 and ip tcp adjust-mss 1360, on both ends of the tunnel. The math behind 1400 is "1500-byte underlay minus worst-case GRE plus IPsec overhead minus margin." The MSS clamping prevents TCP endpoints from negotiating segment sizes that the tunnel cannot carry without fragmentation, which removes the entire PMTUD-black-hole failure class.
If you are debugging an MTU problem in production, the diagnostic is a sized ping with the DF bit set: walk the size up until packets start failing, that is your path MTU, set ip mtu to that value or below. The full cluster reference is at PingLabz GRE Tunnels; the troubleshooting playbook with debug walkthroughs is at GRE Tunnel Troubleshooting Guide.