Path MTU Discovery (PMTUD) is a critical mechanism in IPv6 networking that determines the maximum transmission unit (MTU) size along the network path between two hosts. Unlike IPv4 where PMTUD is optional, IPv6 makes it mandatory because routers are prohibited from fragmenting packets. Understanding PMTUD is essential for maintaining reliable IPv6 connectivity and avoiding the dreaded "black hole" scenarios where packets are silently dropped.
The Maximum Transmission Unit (MTU) is the largest packet size that can be transmitted over a network link without fragmentation. Different network technologies support different MTU sizes:
Network paths often traverse multiple links with varying MTU sizes. Without PMTUD, a sender might transmit packets too large for intermediate links, causing:
PMTUD solves this by dynamically discovering the smallest MTU along the entire path, allowing senders to optimize packet sizes accordingly. This is similar to how Neighbor Discovery Protocol handles address resolution and router discovery in IPv6.
IPv6 PMTUD follows a standardized process defined in RFC 8201. Here's the step-by-step mechanism:
Host A (MTU: 1500) ----------> ... ----------> Host B
|
+---> Assumes path MTU = link MTU (1500 bytes)
When an IPv6 host initiates communication, it assumes the path MTU equals the MTU of its local link-layer interface (typically 1500 bytes for Ethernet). For more on link-local concepts, see link-local addresses function.
The source host sends IPv6 packets sized according to its assumed path MTU. In IPv6, all packets are implicitly marked "Do Not Fragment" - there is no flag to set, fragmentation is simply forbidden at routers.
Host A Router X Host B
| | |
|--[1500-byte pkt]--->| |
| | MTU=1280 |
| | (packet too big!) |
| | |
|<--[ICMPv6 PTB]------| |
| MTU=1280 | |
When a router along the path receives a packet larger than its outgoing interface MTU:
Host A receives ICMPv6 PTB with MTU=1280
|
+---> Updates path MTU cache for destination
|
+---> Retransmits with smaller packet size (1280 bytes)
The source host:
Path: Host A --[MTU 1500]-- Router X --[MTU 1280]-- Router Y --[MTU 1400]-- Host B
| |
| |
First PTB: MTU=1280 (No second PTB needed,
1280 < 1400)
If multiple routers have constrained MTUs, the process repeats iteratively until the smallest MTU is discovered. The final path MTU represents the bottleneck link.
┌─────────────────────────────────────────────────────────────┐
│ IPv6 PMTUD Process Flow │
└─────────────────────────────────────────────────────────────┘
[Start Communication]
│
↓
┌───────────────────┐
│ Assume Path MTU = │
│ Link Layer MTU │
│ (e.g., 1500) │
└────────┬──────────┘
│
↓
┌───────────────────┐
│ Send IPv6 Packet │
│ (size = Path MTU)│
└────────┬──────────┘
│
↓
┌────────────────────────┐
│ Packet reaches router │
│ with smaller MTU? │
└────┬─────────────┬─────┘
│ │
NO │ │ YES
│ │
↓ ↓
[Packet ┌──────────────────┐
delivered]│ Router drops pkt │
│ Sends ICMPv6 PTB │
│ (Type 2, Code 0)│
└────────┬─────────┘
│
↓
┌────────────────────┐
│ Host receives PTB │
│ Updates Path MTU │
│ to reported value │
└────────┬───────────┘
│
↓
┌────────────────────┐
│ Retransmit with │
│ smaller packets │
└────────┬───────────┘
│
└──────> (loop back to "Send IPv6 Packet")
ICMPv6 Packet Too Big (PTB) messages are the core mechanism enabling IPv6 PMTUD:
ICMPv6 Packet Too Big Message Structure:
┌──────────────────────────────────────────┐
│ Type = 2 (Packet Too Big) │
├──────────────────────────────────────────┤
│ Code = 0 │
├──────────────────────────────────────────┤
│ Checksum │
├──────────────────────────────────────────┤
│ MTU (32 bits) │
│ [Next-hop MTU value] │
├──────────────────────────────────────────┤
│ As much of invoking packet as possible │
│ (without exceeding min IPv6 MTU) │
└──────────────────────────────────────────┘
Critical requirement: IPv6 firewalls MUST allow ICMPv6 Type 2 (Packet Too Big) messages to pass through. Blocking these messages breaks PMTUD and creates black hole scenarios.
Many security-conscious administrators mistakenly block all ICMP traffic. For IPv6, this is catastrophic. At minimum, permit:
IPv6 PMTUD differs fundamentally from its IPv4 counterpart:
| Aspect | IPv4 | IPv6 |
|---|---|---|
| Router fragmentation | Allowed (if DF bit not set) | Prohibited (always) |
| Don't Fragment flag | Optional (DF bit in header) | Implicit (no flag needed) |
| Fragment responsibility | Routers or source | Source only |
| Fragment header | Part of base header | Extension header only |
IPv4 packet with DF=0:
Router can fragment --> Multiple fragments delivered
IPv4 packet with DF=1:
Router sends ICMP Type 3 Code 4 (Fragmentation Needed)
IPv4 allows routers to fragment packets when the DF (Don't Fragment) bit is not set. PMTUD in IPv4 works by explicitly setting the DF bit.
All IPv6 packets:
Router CANNOT fragment --> Sends ICMPv6 Type 2 (Packet Too Big)
IPv6 always behaves as if the DF flag is set. Routers are completely prohibited from fragmenting packets, making PMTUD mandatory rather than optional.
The IPv6 minimum MTU guarantee ensures predictable behavior and simplifies implementation.
IPv6 mandates that every link in the Internet must have an MTU of 1280 octets or greater. This is a hard requirement from RFC 8200 (the core IPv6 specification).
For Links with MTU < 1280: If a link physically cannot support 1280-byte packets, link-layer fragmentation and reassembly must be implemented below the IPv6 layer. This is the link layer's responsibility, not IPv6's.
For PMTUD:
When PMTUD fails (due to ICMP filtering), hosts can safely fall back to the 1280-byte minimum:
PMTUD failure detected:
↓
Reduce packet size to 1280 bytes
↓
Continue communication (guaranteed to work)
This fallback provides a safety net, albeit with potential performance reduction for paths that could support larger packets.
A PMTUD black hole occurs when ICMPv6 Packet Too Big messages are filtered or blocked, preventing the source from learning the actual path MTU. The result:
Host A sends 1500-byte packets
↓
Router X drops them (MTU = 1280)
↓
ICMPv6 PTB blocked by firewall
↓
Host A never learns path MTU
↓
Packets continue being dropped silently
↓
Connection appears to "hang" or fail mysteriously
In IPv4, if PMTUD fails and routers can still fragment, communication continues (albeit inefficiently). In IPv6:
IPv4 PMTUD failure:
Router fragments --> Inefficient but works
IPv6 PMTUD failure:
Router drops packet --> COMPLETE FAILURE
IPv6 routers cannot fragment, so PMTUD failures are catastrophic. This makes proper ICMPv6 handling absolutely critical.
Test path MTU by sending packets of increasing size:
# Linux/macOS - Test with 1500-byte packets
ping6 -M do -s 1472 2001:db8::1
# -M do: Prohibit fragmentation (enforce PMTUD)
# -s 1472: 1472 bytes data + 28 bytes (IPv6 + ICMPv6 headers) = 1500 total
# If successful, try larger:
ping6 -M do -s 1500 2001:db8::1
# If fails, try smaller:
ping6 -M do -s 1252 2001:db8::1 # 1280 total
Windows:
ping -6 -f -l 1472 2001:db8::1
# -f: Don't fragment
# -l 1472: Packet size
For comprehensive ping testing guidance, see test IPv6 ping and ICMPv6.
Some traceroute implementations support PMTUD:
# Linux
traceroute6 -M do 2001:db8::1
# This performs traceroute while respecting PMTUD,
# showing where packets get dropped
For detailed traceroute usage, see traceroute IPv6 guide.
Linux:
# View all cached path MTU values
ip -6 route show cache
# Check specific destination
ip -6 route get 2001:db8::1
Example output:
2001:db8::1 via fe80::1 dev eth0 src 2001:db8::100
cache expires 593sec mtu 1280
For TCP connections, monitor the Maximum Segment Size (MSS):
# Capture TCP handshake
tcpdump -i eth0 -nn 'tcp[tcpflags] & (tcp-syn) != 0'
# Look for MSS option in SYN packets
# MSS should be (Path MTU - 60) for IPv6 (40-byte header + 20-byte TCP header)
For more details on packet capture, see capture IPv6 packets with Wireshark.
┌──────────────────────────────────────────────┐
│ IPv6 MTU Troubleshooting Workflow │
└──────────────────────────────────────────────┘
1. Verify Basic Connectivity
↓
ping6 destination
↓
[Success?]
│
├─ NO → [Check IPv6 routing, addressing](troubleshoot-no-ipv6-connectivity)
│
└─ YES
↓
2. Test with Minimum MTU (1280)
↓
ping6 -M do -s 1252 destination
↓
[Success?]
│
├─ NO → Severe connectivity issue (not MTU-related)
│
└─ YES
↓
3. Test with Standard MTU (1500)
↓
ping6 -M do -s 1472 destination
↓
[Success?]
│
├─ NO → MTU issue detected → Proceed to step 4
│
└─ YES → Path MTU = 1500 (no issue)
4. Binary Search for Actual MTU
↓
Test midpoint: 1364 bytes ((1252+1472)/2)
↓
[Success?]
│
├─ YES → Increase size (test 1418)
│
└─ NO → Decrease size (test 1308)
↓
[Repeat until exact MTU found]
5. Verify ICMPv6 PTB Reception
↓
tcpdump -i eth0 'icmp6 and ip6[40] == 2'
(Capture while sending oversized packets)
↓
[Seeing PTB messages?]
│
├─ NO → ICMP filtering detected!
│ → Check firewalls
│ → Configure to allow ICMPv6 Type 2
│
└─ YES → PMTUD working correctly
→ Issue may be elsewhere
6. Check Application-Level Behavior
↓
Test specific protocol (SSH, HTTPS, etc.)
↓
[Works with small packets but hangs on data transfer?]
│
└─ YES → Classic PMTUD black hole
→ Force 1280-byte MTU as workaround
→ Fix ICMP filtering for permanent solution
# Linux
sudo ip link set dev eth0 mtu 1280
# macOS
sudo ifconfig en0 mtu 1280
# Windows (PowerShell as Administrator)
netsh interface ipv6 set interface "Ethernet" mtu=1280
This forces the host to send smaller packets that fit through the constrained path.
Firewall configuration (iptables example):
# Allow ICMPv6 Packet Too Big
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type packet-too-big -j ACCEPT
ip6tables -A OUTPUT -p ipv6-icmp --icmpv6-type packet-too-big -j ACCEPT
ip6tables -A FORWARD -p ipv6-icmp --icmpv6-type packet-too-big -j ACCEPT
Firewall configuration (firewalld example):
# Add ICMPv6 PTB to allowed types
firewall-cmd --permanent --add-icmp-block-inversion
firewall-cmd --permanent --add-icmp-block=packet-too-big --action=accept
firewall-cmd --reload
RFC 4821 defines a technique where TCP can probe for path MTU without relying on ICMP:
# Enable TCP MTU probing
sudo sysctl -w net.ipv4.tcp_mtu_probing=1
# Persist across reboots
echo "net.ipv4.tcp_mtu_probing=1" | sudo tee -a /etc/sysctl.conf
This provides resilience against PMTUD black holes for TCP connections.
Want to verify your IPv6 connectivity is working correctly, including MTU handling? Visit test-ipv6.run for comprehensive IPv6 testing including:
The test runs entirely in your browser and can help identify connectivity issues that might be related to MTU problems.
Path MTU Discovery is a fundamental mechanism in IPv6 networking that addresses the prohibition of router-based fragmentation. By using ICMPv6 Packet Too Big messages, IPv6 hosts dynamically discover the optimal packet size for each destination, ensuring efficient communication without fragmentation.
The key differences from IPv4 - mandatory PMTUD, no router fragmentation, and the 1280-byte minimum MTU guarantee - make IPv6 PMTUD both more critical and more robust. However, these same characteristics make ICMPv6 filtering catastrophic for IPv6 connectivity.
For network administrators, ensuring ICMPv6 Type 2 messages are never blocked is absolutely essential. For developers and users, understanding PMTUD helps diagnose mysterious connectivity issues that manifest as successful connection establishment followed by hung data transfers.
When troubleshooting IPv6 connectivity issues, always consider PMTUD as a potential cause, especially when symptoms include protocol-specific failures or asymmetric behavior. Tools like ping6 with specific packet sizes, traceroute6, and MTU cache inspection can quickly identify path MTU constraints.
Finally, test your IPv6 connectivity regularly using tools like test-ipv6.run to ensure your network configuration supports proper PMTUD and provides optimal IPv6 performance.
Last updated: October 2025