Using the ping Command to Help Determine the Correct MTU Setting for Your Network

In network environments, ensuring that all devices, including nodes and switches, have matching MTU (Maximum Transmission Unit) settings is critical for optimal performance. Mismatched MTU settings can lead to packet fragmentation, which reduces efficiency and can impact application performance. This guide will show how to use the ping command on Linux to verify that the correct MTU is set for your network.

What is MTU and Why It’s Important

MTU refers to the largest size of a packet that can be transmitted over a network without needing to be fragmented. For example, a typical MTU for Ethernet is 1500 bytes, but in some environments, jumbo frames with larger MTU values (such as 9000) are used to enhance performance.

If there’s a mismatch in MTU settings between devices, packets may need to be fragmented, leading to performance degradation. To avoid this, you can use the ping command to check whether all devices support the desired MTU.

Determining the MTU Setting on Linux

On Linux, you can use the ping command with several flags to test the MTU. This is particularly useful for validating if all nodes and networking devices in your environment are using the correct MTU, especially in environments like Nutanix clusters, where performance optimization is essential.

Using ping to Test MTU Settings

To test the MTU, we’ll use the following options:

  • -M do: Tells ping not to fragment the packets (this checks if the network supports the specified MTU).
  • -s: Specifies the ICMP payload size (MTU minus 28 bytes: 20 bytes of IPv4 header plus 8 bytes of ICMP header).
  • -c: Specifies the number of packets to send.

Step 1: Calculate the Packet Size

If you are targeting an MTU of 9000 bytes, subtract 28 from 9000 to get the packet size:

bash
9000 - 28 = 8972

This packet size (8972 bytes) will be used for testing the MTU.

Step 2: Run the ping Command

Run the following command to test the MTU on Linux:

bash
ping REMOTE_HOSTNAME -c 10 -M do -s 8972

In this command:

  • REMOTE_HOSTNAME is the hostname or IP address of the remote device.
  • -c 10 sends 10 pings.
  • -M do ensures the packets aren’t fragmented.
  • -s 8972 sets the packet size to 8972 bytes, assuming an MTU of 9000.

Step 3: Analyze the Output

If the MTU settings match, ping will return normal results, similar to the following:

bash
PING test.example.local (192.168.1.80) 8972(9000) bytes of data.
8972 bytes from test.example.local (192.168.1.80): icmp_seq=1 ttl=64 time=0.432 ms
8972 bytes from test.example.local (192.168.1.80): icmp_seq=2 ttl=64 time=0.418 ms

However, if the MTU is mismatched, you will see one of two errors. If a router or another host on the path has a smaller MTU, it answers with:

bash
From test1.example.local (192.168.1.112) icmp_seq=1 Frag needed and DF set (mtu = 1500)

This message means a device on the path (here 192.168.1.112) has an MTU of 1500 bytes, not 9000, and could not forward the packet because the Don’t Fragment bit is set.

If your own interface has the smaller MTU, the packet never leaves the host and ping prints a local error instead. Newer iputils versions print the first line, older ones the second:

bash
ping: sendmsg: Message too long
ping: local error: message too long, mtu=1500

In that case check the local interface first with ip link show dev eth0 and look at the mtu value.

Example Output for a Mismatched MTU

bash
ping -c 10 -M do -s 8972 test.example.local

Output:

bash
PING test.example.local (192.168.1.80) 8972(9000) bytes of data.
From test1.example.local (192.168.1.112) icmp_seq=1 Frag needed and DF set (mtu = 1500)
From test1.example.local (192.168.1.112) icmp_seq=1 Frag needed and DF set (mtu = 1500)

This indicates that the MTU is mismatched, and the packet size is too large for the network path. The MTU on the device (1500) does not match the desired setting (9000).

Step 4: Find the Largest Size That Works

If you do not know the path MTU, let tracepath discover it. It does not need root:

bash
tracepath -n REMOTE_HOSTNAME

The pmtu value on each hop and the final Resume: pmtu line show the largest packet the path accepts. You can also lower -s by hand until replies come back; the working size plus 28 is the path MTU.

Step 5: Adjust the MTU Setting

If a mismatch is detected, adjust the MTU settings on the network device to match the desired MTU. On Linux you can change it temporarily with ip link set dev eth0 mtu 9000 and make it permanent in your network configuration (for example mtu: 9000 in netplan). Every device in the layer 2 path, including switch ports, must allow the larger frame. After making changes, run the ping command again to verify the MTU setting.

Quick Reference: Sizes and Other Operating Systems

Target MTUIPv4 ping -s sizeIPv6 ping -6 -s size
150014721452
1450 (common VXLAN overlay)14221402
900089728952

IPv6 uses a 40 byte header plus 8 bytes of ICMPv6, so subtract 48 instead of 28.

The same test on other systems:

  • Windows: ping -f -l 1472 HOST (-f sets Don’t Fragment, -l is the payload size)
  • macOS: ping -D -s 1472 HOST (-D sets Don’t Fragment)

FAQ

Why subtract 28 bytes?

-s sets the ICMP data size, not the packet size. The IPv4 header (20 bytes) and the ICMP header (8 bytes) are added on top, so a 1472 byte payload makes a 1500 byte IP packet.

What is the difference between -M do and -M probe?

-M do sets the Don’t Fragment bit and lets the kernel reject packets larger than the path MTU it already knows, which is why you can get a local error. -M probe also sets Don’t Fragment but bypasses the kernel’s cached PMTU, which is useful when you want to probe the path again after changing an MTU.

Why do pods or VMs fail with large transfers but ping works?

Default ping sends 64 byte packets, which always fit. Overlays such as VXLAN, Geneve or WireGuard add headers, so the inner MTU must be lower than the physical one (for example 1450 for VXLAN on a 1500 network). Test with the full size from inside the pod or VM to find the problem.

Do I need root to run these tests?

No. ping -M do -s and tracepath work as a normal user on current Linux distributions.