//------------------------------------------------------------------- //-------------------------------------------------------------------
Fixing MTU Mismatch Issues in Linux

Fixing MTU Mismatch Issues in Linux

MTU (Maximum Transmission Unit) defines the largest packet size that can be transmitted across a network without fragmentation. When devices along a network path have different MTU configurations, MTU mismatch issues happen, which can cause periodic connectivity problems that are very difficult to recognize.

An MTU mismatch happens when parts of a network use different MTU sizes, for example, 9000 vs 1500 bytes. This can disrupt traffic if Path MTU Discovery can’t adjust the packet size. PMTUD relies on ICMP “Fragmentation Needed” messages to tell the sender to send smaller packets. If firewalls block ICMP, PMTUD fails, and packets get dropped, which creates an MTU black hole.

In this guide from PerLod Hosting, you will learn how MTU mismatches cause network issues and discover the best strategies for detection and fixes.

MTU Mismatch Issues Symptoms

MTU mismatch issues can cause periodic connectivity problems that are hard to debug. Simple tests may work, but bigger data transfers can fail, and the exact symptoms depend on the app or protocol.

Here are the most common symptoms of MTU mismatch issues:

1. Connection Establishment vs. Data Transfer Failures:

Initial connections may work, but data transfer can fail or freeze. Small packets like the TCP handshake get through, while larger packets hit the MTU limit and get dropped. A common example is SSH. You can connect and log in, but commands that produce lots of output may hang because the bigger packets can’t pass.

2. Application Failures:

Different apps can fail in different ways when there’s an MTU mismatch.

  • Web browsing: Some sites load, but others hang or only partially load, especially HTTPs.
  • VPN Connections: The VPN adds extra headers, so the usable MTU gets smaller. The VPN stays connected, but websites and transfers may fail or time out.
  • Database Replication: The connection starts, then replication remains when it tries to send large rows or bulk data.
  • File Transfers: Small files work, but large files freeze partway through. They don’t just get slower, they stop.
  • VoIP and Streaming: Calls and video get choppy, pixelated, or drop because packets are lost.

3. Black Hole Symptoms:

MTU black holes happen when oversized packets get dropped with no warning. This usually occurs because routers don’t send ICMP “Fragmentation Needed” messages, often due to firewalls blocking ICMP or router misconfiguration. They’re hard to spot because small tests like ping still work, but real applications that send larger data hit timeouts or random failures.

4. Performance Slow Down Symptoms:

Even if the connection doesn’t completely fail, an MTU mismatch can still slow down performance:

  • Excessive Fragmentation: If packets can be fragmented, routers split large packets into smaller pieces. This adds extra headers, increases CPU work, and if one fragment is lost, the whole packet must be resent.
  • Increased Retransmissions: When large packets get dropped, apps time out and resend data, which wastes bandwidth and adds delay.
  • Higher Latency: Fragmentation and reassembly add processing overhead, so interactive apps like SSH or real-time audio and video feel slower.

5. Environmental Factors:

Some network setups make MTU mismatch issues more common:

  • Tunneling Protocols: GRE, IPsec, and VXLAN add extra headers, which lower the usable MTU, and it drops even more if tunnels are stacked.
  • Cloud and Container Networks: Overlays in environments like AWS, Azure, and Kubernetes often reduce MTU from 1500 to around 1450 or less.
  • WAN Links: PPPoE, DSL, and some MPLS networks use non-standard MTUs like 1492, which can clash with Ethernet 1500.

Systematic Testing To Detect MTU Mismatch Issues

You need a step-by-step method to find MTU mismatches. This can be done by systematic testing, including checking the MTU at each hop, and make sure the whole network path can carry the packet size you need.

You can run these MTU mismatch issues tests directly on your VPS server to confirm the real path MTU between your host and the destination.

Check Current MTU Configuration

Before testing the network path, first check the MTU on your local network interface. On Linux, you can run the ip command to display interface details, including MTU:​

ip link show

In the output, look for the MTU field:

2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
    link/ether 08:00:27:3f:5a:87 brd ff:ff:ff:ff:ff:ff

For a specific interface, you can use the command below:

ip link show eth0

Alternatively, you can use the commands below:

ip addr show eth0
ifconfig eth0

Also, you can check the MTU value directly from the system filesystem:

cat /sys/class/net/eth0/mtu

For a comprehensive view of all interface statistics, including MTU mismatches, you can use the command below:

netstat -i

In the output, you will see MTU alongside packet statistics:

Kernel Interface table
Iface   MTU   RX-OK RX-ERR RX-DRP RX-OVR    TX-OK TX-ERR TX-DRP TX-OVR Flg
eth0   1500   25055      0      0 0         14239      0      0      0 BMRU
lo    65536      16      0      0 0            16      0      0      0 LRU

Test MTU with Ping Command

Ping is the main tool for checking MTU mismatches on a network path. It sends test packets of specific sizes with “Don’t Fragment” enabled, so you can see the largest packet size that can pass without being split.

The basic syntax for MTU mismatches testing with ping on Linux looks like this:

ping -M do -s <packet_size> -c 4 <destination>

Command options:

  • -M do: Turns on “Don’t Fragment” (DF). If the packet is too big, it gets dropped instead of being split.
  • -s <packet_size>: Sets the ping payload size in bytes. Total packet size is payload + 28 bytes for IP and ICMP headers.
  • -c 4: Sends 4 pings, then stops.
  • <destination>: The host or IP you’re testing.

Calculating Packet Size:

To test a specific MTU with ping, set the payload size to:

MTU − 28 (20 bytes IP header + 8 bytes ICMP header)

For example:

  • MTU 1500: payload 1472 (1500 − 28).
  • MTU 9000: payload 8972 (9000 − 28).
  • MTU 1400: payload 1372 (1400 − 28).

Test standard Ethernet MTU 1500 bytes with:

ping -M do -s 1472 -c 4 192.168.1.1

Here is an expected output when MTU is supported:

PING 192.168.1.1 (192.168.1.1) 1472(1500) bytes of data.
1480 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=0.432 ms
1480 bytes from 192.168.1.1: icmp_seq=2 ttl=64 time=0.418 ms
1480 bytes from 192.168.1.1: icmp_seq=3 ttl=64 time=0.401 ms
1480 bytes from 192.168.1.1: icmp_seq=4 ttl=64 time=0.387 ms

--- 192.168.1.1 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3067ms
rtt min/avg/max/mdev = 0.387/0.409/0.432/0.018 ms

Test Jumbo frames MTU 9000 bytes:

ping -M do -s 8972 -c 4 10.0.0.50

If the packet size exceeds the path MTU, you’ll receive an error including fragmentation is needed:

PING 192.168.1.1 (192.168.1.1) 1472(1500) bytes of data.
From 192.168.1.254 icmp_seq=1 Frag needed and DF set (mtu = 1400)
From 192.168.1.254 icmp_seq=2 Frag needed and DF set (mtu = 1400)

To find the largest MTU the path supports, start with a large ping payload and lower it until the ping succeeds. You can automate this with a simple loop that retries with smaller sizes:

for size in 1500 1480 1460 1440 1420 1400; do
  echo "Testing MTU $((size + 28)) (payload $size):"
  ping -M do -s $size -c 2 -W 2 192.168.1.1 >/dev/null 2>&1
  if [ $? -eq 0 ]; then
    echo "  SUCCESS - Maximum MTU is $((size + 28))"
    break
  else
    echo "  FAILED"
  fi
done

To find the exact path MTU faster, you can use a binary search. Test a middle packet size, then go higher if it works or lower if it fails, until you narrow down the maximum size that passes:

#!/bin/bash
destination="$1"
low=68          # Minimum IP MTU
high=1500       # Standard MTU (adjust higher for jumbo frames)

echo "Finding optimal MTU for $destination..."

while [ $((high - low)) -gt 1 ]; do
  mid=$(((high + low) / 2))
  payload=$((mid - 28))
  
  ping -M do -s $payload -c 1 -W 2 "$destination" >/dev/null 2>&1
  
  if [ $? -eq 0 ]; then
    low=$mid
    echo "MTU $mid works"
  else
    high=$mid
    echo "MTU $mid fails"
  fi
done

echo "Maximum MTU: $low bytes"

Save this as find-mtu.sh file, make it executable, and then run:

./find-mtu.sh 192.168.1.1

Test MTU with Tracepath Command

Tracepath shows the route to a destination and finds the MTU mismatches along the way. Unlike ping, it can point out which hop causes the MTU to drop.

Basic usage looks like this:

tracepath 192.168.1.1

Example output:

 1?: [LOCALHOST]                        pmtu 1500
 1:  gateway                             0.411ms 
 2:  10.0.1.1                            1.123ms 
 3:  203.0.113.1                         5.632ms pmtu 1400
 4:  203.0.113.254                      12.455ms 
 5:  192.168.1.1                        18.234ms reached
     Resume: pmtu 1400 hops 5 back 5

Explanation:

  • pmtu 1500: The path MTU starts at 1500 bytes, usually your local interface.
  • pmtu 1400: At that hop, the path MTU drops to 1400 bytes.
  • reached: The destination is reachable.
  • Resume: The summary shows the final path MTU, for example, 1400 bytes.

Tracepath is useful because it shows where the MTU changes, which helps you find the device causing the mismatch.

Tracepath options include:

tracepath -n 192.168.1.1        # Show IP addresses without DNS resolution
tracepath -b 192.168.1.1        # Show both hostnames and IP addresses
tracepath -m 20 192.168.1.1     # Set maximum hops to 20
tracepath -l 9000 192.168.1.1   # Set initial packet length (for jumbo frames)

To test if the path supports a specific MTU, you can use the -l option:

tracepath -l 9000 10.0.0.50

If the output shows MTU reductions, you’ve found where the mismatch happens.

Detect ICMP filtering with tcpdump

ICMP filtering can break Path MTU Discovery and create MTU black holes. You can test whether ICMP “Fragmentation Needed” messages are being delivered:

Send oversized packets with the DF bit set:

ping -M do -s 1500 -c 5 <destination>

Monitor with tcpdump on the source host:

sudo tcpdump -i eth0 icmp -n -v

You must look for:

  • ICMP Fragmentation Needed messages appear: PMTUD is working, and you’ll see errors like Destination unreachable (Fragmentation needed).
  • No ICMP messages show up: ICMP is likely blocked somewhere, so packets get dropped silently, creating an MTU black hole.

Specific tcpdump filter for fragmentation needed messages include:

sudo tcpdump -i eth0 'icmp[0] == 3 and icmp[1] == 4' -n -v

This filter shows only ICMP Type 3 Code 4 (Fragmentation Needed) messages, the specific ICMP message used for PMTUD.

VPN Tunnel Testing

VPN tunnels add extra headers, so the usable MTU inside the tunnel is smaller. To find the real MTU, you can ping a host through the tunnel with DF enabled and adjust the payload size until it works.

For IPsec VPNs: IPsec adds extra header data, usually about 50 to 73 bytes, depending on the encryption and settings:

ping -M do -s 1422 -c 4 <destination_through_vpn>

If 1422 succeeds, the effective MTU is 1450 bytes (1422 payload + 28 headers).

For GRE tunnels: GRE adds 24 bytes of overhead (20-byte IP header + 4-byte GRE header):

ping -M do -s 1448 -c 4 <destination_through_gre>

For GRE over IPsec: Combined overhead is about 80 bytes:

ping -M do -s 1392 -c 4 <destination>

Start with a smaller packet size, then increase it step by step until it fails. This helps you find the largest MTU that still works end-to-end:

for size in 1372 1400 1422 1450 1472; do
  echo "Testing payload size $size (MTU $((size + 28))):"
  ping -M do -s $size -c 2 -W 2 <vpn_destination>
  echo ""
done

For deep analysis, you can capture actual traffic and examine fragmentation behavior:

Capture oversized packets with the command below:

sudo tcpdump -i eth0 -w mtu-test.pcap 'greater 1500'

This captures all packets exceeding 1500 bytes, which shouldn’t exist on standard Ethernet if PMTUD is working correctly.

Capture ICMP and test traffic with the command below:

sudo tcpdump -i eth0 -n -v 'icmp or (host 192.168.1.1 and tcp port 22)'

You can transfer the capture file to a system with Wireshark and apply filters to analyze it.

Automated MTU Discovery Script

Here is a comprehensive script that combines multiple MTU testing methods:

#!/bin/bash
# MTU Discovery and Validation Script

DESTINATION="$1"

if [ -z "$DESTINATION" ]; then
  echo "Usage: $0 <destination_ip_or_hostname>"
  exit 1
fi

echo "=== MTU Discovery for $DESTINATION ==="
echo ""

# Check local interface MTU
echo "Local interface MTU:"
ip link show | grep "mtu" | head -1
echo ""

# Test standard MTU
echo "Testing standard MTU (1500 bytes):"
if ping -M do -s 1472 -c 2 -W 2 "$DESTINATION" >/dev/null 2>&1; then
  echo "  ✓ MTU 1500 supported"
else
  echo "  ✗ MTU 1500 NOT supported - running detailed tests..."
  echo ""
  
  # Find maximum MTU
  echo "Finding maximum MTU:"
  for mtu in 1400 1300 1200 1100 1000; do
    payload=$((mtu - 28))
    if ping -M do -s $payload -c 1 -W 2 "$DESTINATION" >/dev/null 2>&1; then
      echo "  ✓ Maximum MTU: $mtu bytes"
      break
    fi
  done
fi

echo ""
echo "Path analysis with tracepath:"
tracepath "$DESTINATION" | head -20
echo ""

echo "=== Test complete ==="

Save it as mtu-discovery.sh file, make it executable, and run with the commands below:

chmod +x mtu-discovery.sh
./mtu-discovery.sh 192.168.1.1

Fix MTU Mismatch Issues with Best Strategies

Once MTU mismatch issues are found, you can use several strategies to solve them. The optimal solution depends on your network topology, infrastructure control, and operational requirements.

Here are the most effective strategies you can use to fix the MTU mismatch issues:

1. Standardize MTU Across All Devices

The most powerful solution is to ensure all devices in the network path use consistent MTU values. This removes mismatches at the source rather than working around them.

To find all devices in the path, you can use traceroute or tracepath to map the complete network path:

traceroute -n 192.168.1.1

Set the same MTU on all routers, switches, and hosts on the path. For most networks, the safe default is 1500 bytes.

Only use 9000-byte jumbo frames if every device on the path supports it end-to-end; otherwise, you’ll see fragmentation or dropped packets.

Verify consistency after changes with the command below:

tracepath 192.168.1.1

The output should show a consistent PMTU value throughout the path.

2. Temporarily Change MTU on Linux Interface

For quick testing, you can temporarily change your interface MTU so you can confirm the issue is MTU-related before making permanent changes.

On Linux, you can use the command below to update the MTU immediately:

sudo ip link set dev eth0 mtu 1400

Replace eth0 with your actual interface name and 1400 with the desired MTU value.

Verify the change with the command below:

ip link show eth0

Look for mtu 1400 in the output to confirm the change is applied.

Use the ifconfig command to bring up the interface after the MTU change:

sudo ifconfig eth0 mtu 1400 up

Important notes about temporary changes:

  • These changes are lost after a system reboot.
  • The interface may briefly disconnect during the MTU change.
  • Applications with active connections may need to reconnect.
  • Test connectivity after changing MTU to ensure the value is correct.

After changing the MTU, immediately test that it resolved the issue with the commands below:

ping -M do -s 1372 -c 4 192.168.1.1    # Should succeed with MTU 1400
ssh [email protected]                    # Test application connectivity

3. Permanently Configure MTU on Linux Systems

To make MTU changes persistent across reboots, you must update your network configuration files. You can use different methods depending on your Linux distro and network management system:

Method A. Using NetworkManager on RHEL, CentOS, Fedora, and modern Ubuntu Desktop

List existing connections with the nmcli command:

nmcli connection show

Set MTU for a specific connection:

sudo nmcli connection modify "Wired connection 1" ethernet.mtu 9000

Replace “Wired connection 1” with your actual connection name and 9000 with your desired MTU.

Reapply the configuration without disconnecting:

sudo nmcli device reapply eth0

Or restart the connection, which causes a brief disconnection:

sudo nmcli connection down "Wired connection 1"
sudo nmcli connection up "Wired connection 1"

Verify the configuration with the command below:

nmcli connection show "Wired connection 1" | grep mtu

You should see “ethernet.mtu: 9000” in the output.

Connection profiles are stored in /etc/NetworkManager/system-connections/ file. Edit the appropriate file:

sudo vi /etc/NetworkManager/system-connections/eth0.nmconnection

Add or modify the MTU setting in the [ethernet] section:

[ethernet]
mtu=9000

Reload the configuration with the commands below:

sudo nmcli connection load /etc/NetworkManager/system-connections/eth0.nmconnection
sudo nmcli device reapply eth0

Method B. Using Legacy Network Scripts on older RHEL and CentOS distros

On older Red Hat-based systems using network scripts, you can edit the interface configuration file:

sudo vi /etc/sysconfig/network-scripts/ifcfg-eth0

Add or modify the MTU line:

DEVICE=eth0
BOOTPROTO=dhcp
ONBOOT=yes
TYPE=Ethernet
USERCTL=yes
PEERDNS=yes
IPV6INIT=no
MTU=1400

Restart networking to apply changes:

sudo systemctl restart network

Or you can restart just the specific interface:

sudo ifdown eth0 && sudo ifup eth0

Verify the configuration with the command below:

ip link show eth0 | grep mtu

Method C. Using systemd-networkd on modern systemd-based systems

Many modern distributions use systemd-networkd for network configuration. You can create or edit a network file with the command below:

sudo vi /etc/systemd/network/10-eth0.network

Add the MTU configuration:

[Match]
Name=eth0

[Network]
DHCP=yes

[Link]
MTUBytes=9000

For static IP configuration:

[Match]
Name=eth0

[Link]
MTUBytes=1400

[Network]
Address=192.168.1.100/24
Gateway=192.168.1.1
DNS=8.8.8.8

Restart systemd-networkd and verify the configuration with the commands below:

sudo systemctl restart systemd-networkd
networkctl status eth0

In the output, you must see MTU: 1400 or your configured value.

Method D. Use Netplan on Ubuntu 18.04+ and Ubuntu Server

Ubuntu uses Netplan for network configuration. Netplan reads YAML files and then generates the actual settings for the backend it uses, usually NetworkManager or systemd-networkd.

Edit the Netplan configuration file with the command below:

sudo vi /etc/netplan/01-netcfg.yaml

Configure MTU in the YAML file:

For DHCP with custom MTU:

network:
  version: 2
  renderer: networkd
  ethernets:
    eth0:
      dhcp4: true
      mtu: 1400

For static IP with custom MTU:

network:
  version: 2
  renderer: networkd
  ethernets:
    eth0:
      addresses:
        - 192.168.1.100/24
      gateway4: 192.168.1.1
      nameservers:
        addresses:
          - 8.8.8.8
          - 8.8.4.4
      mtu: 9000

For bonded interfaces (LACP) with custom MTU:

network:
  version: 2
  renderer: networkd
  ethernets:
    eth0:
      dhcp4: no
    eth1:
      dhcp4: no
  bonds:
    bond0:
      interfaces:
        - eth0
        - eth1
      parameters:
        mode: 802.3ad
        mii-monitor-interval: 100
      mtu: 9000
      addresses:
        - 10.0.0.10/24
      gateway4: 10.0.0.1

Test the configuration before applying and apply the configuration permanently:

sudo netplan try
sudo netplan apply

Verify the configuration:

ip link show eth0 | grep mtu

Method E. Use /etc/network/interfaces on Debian and older Ubuntu

On Debian and older Ubuntu systems using ifupdown, you can edit the interfaces file:

sudo vi /etc/network/interfaces

Add MTU configuration:

For DHCP:

auto eth0
iface eth0 inet dhcp
    mtu 1400

For static IP:

auto eth0
iface eth0 inet static
    address 192.168.1.100
    netmask 255.255.255.0
    gateway 192.168.1.1
    mtu 9000

Alternative syntax using the post-up command:

auto eth0
iface eth0 inet dhcp
    post-up /sbin/ifconfig eth0 mtu 1400

Restart networking or restart the specific interface:

sudo systemctl restart networking
sudo ifdown eth0 && sudo ifup eth0

Method F. Use DHCP Client Configuration

When using DHCP, you can configure the DHCP client to request or override the MTU:

Edit the dhclient configuration:

sudo vi /etc/dhcp/dhclient.conf

Add lines to set MTU:

To use a specific MTU regardless of the DHCP server:

supersede interface-mtu 1400;

To set a default if DHCP doesn’t provide MTU:

default interface-mtu 1400;

Restart the network interface to apply DHCP changes:

sudo dhclient -r eth0  # Release current lease
sudo dhclient eth0     # Obtain new lease

4. TCP MSS Clamping with iptables

TCP MSS clamping is a workaround for MTU problems in TCP connections. It prevents MTU issues for TCP traffic by manipulating the TCP handshake, so packets stay small enough for the path MTU, which avoids fragmentation and drops.

MSS clamping is particularly useful in scenarios where you cannot modify MTU on all deviceslike across an ISP, or when using VPN tunnels where encapsulation lowers the usable MTU.

MSS is the TCP data size limit, calculated as:

MSS = MTU − 20 (IP header) − 20 (TCP header)

For example:

  • MTU 1500: MSS 1460 bytes.
  • MTU 1400: MSS 1360 bytes.

Using iptables for MSS Clamping: Add MSS clamping with an iptables TCPMSS rule, use FORWARD on a router or gateway (transit traffic), and OUTPUT for traffic generated locally.

Clamp to PMTU (Path MTU Discovery):

sudo iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

This adjusts MSS based on the discovered path MTU, which is the most flexible method.

Clamp to specific MSS value:

sudo iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1360

Use this when you know the exact MSS needed, which is common for VPS gateways.

For VPN tunnels (IPsec) on the gateway:

sudo iptables -A FORWARD -s 10.1.0.0/16 -o eth0 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1360

This clamps MSS for traffic from the VPN network going out interface eth0.

For GRE tunnels:

sudo iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1436

GRE overhead is around 24 bytes, so MSS should be reduced accordingly.

To make iptables rules persistent, create a systemd service:

sudo vi /etc/systemd/system/mss-clamping.service

Add the following content:

[Unit]
Description=TCP MSS Clamping for MTU
After=network.target

[Service]
Type=oneshot
ExecStart=/usr/sbin/iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

Enable and start the service with the commands below:

sudo systemctl enable mss-clamping.service
sudo systemctl start mss-clamping.service

Use firewalld for MSS clamping on RHEL:

sudo firewall-cmd --permanent --add-rich-rule='rule tcp-mss-clamp value=pmtu'
sudo firewall-cmd --reload

Or with a specific value:

sudo firewall-cmd --permanent --add-rich-rule='rule tcp-mss-clamp value=1360'
sudo firewall-cmd --reload

Verify MSS clamping is active with the command below:

sudo tcpdump -i eth0 'tcp[tcpflags] & tcp-syn != 0' -v -n

Look for MSS values in SYN packets. They should match your clamped value.

5. Adjust MTU on Tunnel Interfaces

When you use tunnels (VPN, GRE, VXLAN), the tunnel adds extra headers, so you should lower the tunnel interface MTU to leave room for that overhead.

For GRE tunnels, for example, Cisco IOS:

interface Tunnel0
ip mtu 1476
ip tcp adjust-mss 1436
tunnel source GigabitEthernet0/0
tunnel destination 203.0.113.1

For IPsec VPN. for example, strongSwan on Linux, edit /etc/ipsec.conf file:

conn myvpn
leftsubnet=10.1.0.0/16
rightsubnet=10.2.0.0/16
fragmentation=yes
mtu=1400

For OpenVPN, edit the server configuration:

tun-mtu 1400
mssfix 1360

For WireGuard:

sudo ip link set dev wg0 mtu 1420

Make it persistent in WireGuard configuration:

[Interface]
MTU = 1420

6. Linux kernel MTU probing

Linux has a feature called TCP MTU probing that can adjust TCP packet size even when ICMP is blocked. It’s off by default, but you can enable it with Linux kernel probing.

Check the current setting with the command below:

sysctl net.ipv4.tcp_mtu_probing

Enable TCP MTU probing with the following command:

sudo sysctl -w net.ipv4.tcp_mtu_probing=1
  • 0: Disabled
  • 1: Enabled when an ICMP black hole is detected
  • 2: Always enabled

Make it permanent by editing /etc/sysctl.conf file:

sudo vi /etc/sysctl.conf

Add this to the file:

net.ipv4.tcp_mtu_probing=1

Apply without reboot:

sudo sysctl -p

Adjust base MSS for probing:

sudo sysctl -w net.ipv4.tcp_base_mss=1024

Make permanent in /etc/sysctl.conf:

net.ipv4.tcp_base_mss=1024

After implementing any MTU fix, verify that it resolves the issue.

You can test with ping:

ping -M do -s 1472 -c 10 destination

Test application connectivity:

ssh user@destination "cat /var/log/syslog | head -1000"
wget https://destination/large-file.iso
mysql -h destination -e "SELECT * FROM large_table LIMIT 1000"

Monitor for errors:

netstat -s | grep -i fragment
netstat -s | grep -i retrans

Verify MTU consistently:

tracepath destination

Check for TCP retransmissions:

ss -ti | grep retrans

FAQs

What’s the fastest way to confirm MTU mismatch issues?

Use a DF ping to confirm big packets can’t pass: The ping -M do -s payload tests a target MTU (payload + 28 bytes for IPv4 ICMP).

Why do MTU mismatch issues feel random in production?

MTU issues can look random; small packets work, but larger ones get dropped or fragmented. If ICMP “Fragmentation Needed” messages are blocked, PMTUD can’t fix it, so connections start, but data hangs or times out.

If I can’t change MTU everywhere, what’s the safest production workaround?

If you can’t standardize MTU, you can use TCP MSS clamping to keep TCP packets small enough, especially when ICMP is blocked.

Conclusion

MTU mismatch issues happen when devices on the same network path use different MTU sizes, often made worse when ICMP is blocked, and Path MTU Discovery can’t work. They usually look like connects fine, then hang or time out when sending real data, which affects things like SSH, HTTPS, VPNs, file transfers, databases, and VoIP.

You can find them by testing packet sizes end-to-end, checking hop-by-hop MTU drops, and inspecting traffic for drops and fragments.

Fixes include using a consistent MTU everywhere, lowering MTU on tunnels, using TCP MSS clamping when you can’t change the network, and enabling TCP MTU probing on Linux if ICMP is blocked.

We hope you enjoy this guide on MTU mismatch issues. Subscribe to X and Facebook to get the latest articles and updates.

For further reading:

Resolve Kubernetes MetalLB External IP not reachable

Fix MySQL table is full Error

Post Your Comment

PerLod delivers high-performance hosting with real-time support and unmatched reliability.

Contact us

Payment methods

payment gateway
Perlod Logo
Privacy Overview

This website uses cookies so that we can provide you with the best user experience possible. Cookie information is stored in your browser and performs functions such as recognising you when you return to our website and helping our team to understand which sections of the website you find most interesting and useful.