Fragmentation
MTU and MSS both describe how TCP tries to avoid ever creating a packet too large for the path it's crossing — negotiating a segment size upfront, discovering the path's real ceiling when the negotiated value turns out to be too optimistic. Fragmentation is what happens when that avoidance fails: an IP packet that's too large for a link along its path gets split into smaller pieces so it can be carried anyway. It's a real mechanism, defined since the earliest IP specification, and it's also one this module has already mentioned in a distinctly cautionary tone — the previous two articles both pointed to fragmentation-avoidance (the Don't Fragment flag, PMTUD, MSS clamping) as the preferred outcome, not fragmentation itself. This article explains why.
How a packet actually gets split
When a router needs to forward an IP packet onto a link whose MTU is smaller than the packet's own size, and the packet's Don't Fragment (DF) flag is not set, the router is permitted to split it into multiple smaller IP packets — fragments — each carrying a portion of the original packet's data, plus its own copy of the original IP header with a few fields adjusted specifically to support reassembly:
- Identification — the same value across every fragment of the same original packet, so the receiving host knows which fragments belong together.
- Fragment offset — where, in the original unfragmented packet, this particular fragment's data belongs, letting the receiver reassemble the pieces in the correct order even if they arrive out of sequence.
- More Fragments flag — set on every fragment except the last, so the receiver knows when it has received the final piece and can consider reassembly complete.
Original IP packet, 3000 bytes, MTU along one hop is only 1500
Fragment 1: offset 0, 1480 bytes of data, More Fragments = 1
Fragment 2: offset 1480, 1480 bytes of data, More Fragments = 1
Fragment 3: offset 2960, 40 bytes of data, More Fragments = 0
Each fragment travels as its own independent IP packet from that point onward — including, potentially, taking a different route than its siblings, since routing decisions are made per-packet. Reassembly happens only at the final destination host, never at an intermediate router; a router that fragments a packet has no further involvement in putting it back together.
Why fragmentation is genuinely risky, not just inefficient
Splitting a packet sounds like a reasonable, low-drama accommodation. The first problem with it is the one worth sitting with before anything else: one lost fragment loses the whole packet. IP itself has no retransmission mechanism — that's TCP's job, one layer up — and TCP only sees a segment as lost or not; it has no visibility into individual IP fragments at all. If even one fragment out of several goes missing, the receiving host can never complete reassembly, and the entire original packet is effectively lost, even though most of its fragments arrived successfully. The retransmission that follows, driven by TCP up at the transport layer, resends the whole original segment, throwing away every fragment that did make it through.
That single fact — a 3-fragment packet is only as reliable as its least reliable fragment — is most of the reason this module keeps steering away from fragmentation. Two further problems compound it, and they're worth knowing but less central than the one above:
- Reassembly costs memory and time on the receiver. The receiving host has to buffer incomplete data and wait, holding partially-reassembled packets until either every fragment arrives or a timeout expires. That's a real resource cost, and it's exploitable: an attacker can send a stream of packets designed to look like the start of fragmented data that never completes, forcing a target host to hold reassembly buffers open unnecessarily.
- Fragmentation has a documented history as an attack vector. Overlapping fragment offsets, and fragments crafted to reassemble into something different than what a security device inspected before reassembly happened, have both been real, exploited techniques for evading firewalls and intrusion-detection systems. RFC 8900, a more recent IETF document, is titled plainly "IP Fragmentation Considered Fragile" and lays out this case in detail.
Why modern practice avoids it wherever possible
Given that history, the prevailing modern approach — reflected directly in MTU's coverage of the Don't Fragment flag and Path MTU Discovery, and in MSS's coverage of MSS clamping — is to prevent fragmentation from ever being necessary in the first place, rather than relying on it to quietly patch over an oversized packet. A TCP sender that has correctly discovered the path's true MTU, and negotiated (or been clamped to) an MSS that respects it, should essentially never produce a packet that needs mid-path fragmentation at all. Fragmentation, under this model, is a fallback for when something in that chain has gone wrong — a black hole where PMTUD's ICMP messages are being silently dropped, or a route change that shifted traffic onto a smaller-MTU link mid-connection — not a routine, expected part of normal operation.
This is also precisely why QUIC, the transport underneath HTTP/3 (covered later in this course), disables IP-level fragmentation entirely for its own packets and instead handles any necessary size adaptation at its own layer, above IP — a direct, modern design response to exactly the fragility RFC 8900 documents.
Confirming whether fragmentation is actually happening
A packet capture shows fragmentation directly, through the same offset and flag fields described above:
10:45:01.100220 IP 10.0.5.15 > 198.51.100.20: (frag 51422:1480@0+)
10:45:01.100340 IP 10.0.5.15 > 198.51.100.20: (frag 51422:1480@1480+)
10:45:01.100410 IP 10.0.5.15 > 198.51.100.20: (frag 51422:40@2960)
tcpdump's (frag 51422:1480@0+) notation reads directly against the fields described earlier: 51422 is the shared identification value tying all three lines together as pieces of the same original packet, 1480 is each fragment's data length, @0, @1480, @2960 are the offsets, and the trailing + on the first two lines corresponds to the More Fragments flag being set — absent on the final, 40-byte fragment, which is how a receiver knows reassembly is complete. Seeing this pattern on a production path where it wasn't expected is itself a signal worth investigating — it usually means either the Don't Fragment flag wasn't set on the sending side, or something changed along the route that PMTUD hasn't yet caught up with.
Practical scenario: an intermittent, hard-to-reproduce failure over a site-to-site VPN
An application transferring moderately large payloads between two office sites connected by a site-to-site IPsec VPN works reliably most of the time, but a small percentage of transfers fail outright, and the failures don't correlate cleanly with time of day, load, or any single payload size threshold the team has been able to pin down through testing alone.
A capture at the VPN gateway on the sending side, taken during a reproduced failure, shows fragmented packets — multiple lines sharing an identification value, as in the example above — specifically for the failing transfers, while the successful, smaller transfers show no fragmentation at all. The VPN tunnel's own encapsulation (IPsec's ESP header, plus the outer IP header wrapping the original packet) reduces the effective MTU available to the original, inner packet below the gateway interface's nominal 1500 bytes — a detail MSS already flagged as a common, legitimate reason to see a reduced MSS. If the endpoints inside the tunnel negotiated their MSS based on the tunnel interface's nominal MTU rather than the smaller effective MTU left over after encapsulation overhead, larger transfers routinely exceed what the tunnel can actually carry without fragmenting — and fragmented ESP-encapsulated traffic is exactly the kind of traffic some intermediate firewalls and NAT devices along a real-world path are configured to drop outright, on the reasonable but here inconvenient theory that fragmented, encrypted traffic is unusually hard to inspect safely.
The concrete fix is applying MSS clamping specifically at the VPN gateway's tunnel interface, accounting for the tunnel's own overhead — the same iptables mechanism MSS demonstrated, applied at the point where the encapsulation actually happens, so the inner TCP connections never negotiate an MSS that doesn't already account for the tunnel's real available space:
sudo iptables -t mangle -A FORWARD -o tun0 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
Changing MSS clamping or MTU settings on a live VPN gateway can disrupt every existing tunnel session
A site-to-site VPN gateway typically serves every connection between the two sites, not just the application experiencing the intermittent failure. Before applying any change: confirm the current tunnel interface MTU (ip link show tun0) and any existing clamp rules (iptables -t mangle -L -n -v), apply the change during a scheduled maintenance window with both sites aware, and have a rollback command ready to remove the rule immediately if existing traffic is affected unexpectedly. Test the specific failing transfer size afterward to confirm the fix, rather than assuming the rule alone resolved it.
Practice exercises
- Using the three-fragment example in this article, explain exactly what happens if the middle fragment (offset 1480) is lost in transit but the first and last fragments both arrive successfully — does the receiving host end up with a usable, if partial, packet, or nothing at all?
- Explain why QUIC's decision to avoid IP-level fragmentation entirely, mentioned in this article, is a direct response to the specific failure modes described here — which of the risks listed does avoiding fragmentation altogether sidestep completely?
- A colleague suggests that since fragmentation is a standard, documented IP feature, there's no reason to actively avoid it through MTU and MSS tuning — the network will just handle it. Using this article's discussion of loss amplification and the security history of fragmentation, write a short, concrete rebuttal.
This closes the TCP deep-dive: from the handshake that starts a connection, through the windows and algorithms that govern how much data moves and how fast, down to the hard physical size limit every one of those segments still has to respect. The next module in this course turns from TCP's own internals to the protocols built on top of it — starting with the everyday exchange every one of these mechanisms has been quietly supporting the whole time: an HTTP request and response.
Sources
- IETF, RFC 791 – Internet Protocol — defines the original IPv4 fragmentation fields (Identification, Flags, Fragment Offset).
- IETF, RFC 8900 – IP Fragmentation Considered Fragile