Skip to main content

ICMP, Ping, TTL and Path MTU Discovery

TL;DR
  • ICMP (RFC 792) is IP's error and diagnostic channel. It rides directly in IP packets (protocol number 1), and its header is 1 byte type, 1 byte code, 2 bytes checksum, then message-specific data.
  • Ping sends an Echo Request (type 8) and waits for an Echo Reply (type 0). The round trip time is measured at the sender. A default ping is 84 bytes on the wire: 20 IP + 8 ICMP + 56 payload.
  • TTL is a hop count, not a time. Every router decrements it; at 0 the router drops the packet and sends Time Exceeded (type 11, code 0). IPv6 calls it Hop Limit.
  • Path MTU Discovery depends on ICMP: a router that cannot forward a packet with DF set drops it and returns type 3 code 4 (IPv4) or Packet Too Big, type 2 (IPv6). Block that message and large transfers hang while small ones work.
  • Blocking all ICMP is not "safe". Filter selectively: blanket blocking breaks PMTUD, and on IPv6 it breaks neighbour discovery too.

Mental model​

ANALOGYEveryday

The postal service sends you two kinds of slips. One is "return to sender, address unknown", a note from a sorting office that could not deliver your letter and says why. The other is a delivery confirmation you request on purpose: you send a letter to a friend asking "please reply the moment you get this", then time the round trip.

Where it breaks: the slips themselves travel by post. A sorting office may be too busy to write one, or may have a policy of never writing them, so no slip does not mean the letter arrived.

ANALOGYFor engineers

ICMP is the error and diagnostic channel of IP, a bit like stderr and exit codes for the network: the data path stays silent on success and reports failures out of band. Ping is a health-check RPC at layer 3 with no port, no connection and no application behind it.

Where it breaks: stderr is reliable and unconditional. ICMP is best effort, itself subject to loss, rate limiting and filtering, and routers answer it on a slow path, so absence of a message is weak evidence.

How it works​

ICMP is inside IP​

ICMP messages are carried in IP packets with the protocol field set to 1 (IP packet, RFC 792). There is no TCP or UDP header and no port. Every message starts the same way:

typecodechecksumidentifiersequencepayloadtypecodechecksumunusedoriginal IP header + 8 bytesecho messageecho: 4 Becho, 56 B by defaulterror messageerror: 4 B, unusederror: quoted packet
Top: an echo message. The 4-byte rest of header holds identifier and sequence number. Bottom: an error message. It leaves that word unused and appends the start of the packet that caused the error, so the sender can match the error to a socket.

For an error message the sender gets the offending packet's IP header plus the first 8 bytes of its payload (RFC 792). Eight bytes is enough to cover the source and destination ports of TCP and UDP, so the host can find the socket that sent the packet. Modern routers often quote more (RFC 1812 asks for as much as fits in 576 bytes), and RFC 4884 adds a length field and extension objects. Two rules stop error storms (RFC 1122, section 3.2.2): never send an ICMP error about an ICMP error, and never send one for a broadcast or a non-first fragment.

Ping: echo request and reply​

ping builds an Echo Request, type 8, code 0, with an identifier (to tell concurrent pings apart), a sequence number that increments, and a payload. The target copies all three into an Echo Reply, type 0, and sends it back. Ping notes the time when it sent each request and subtracts it from the arrival time of the matching reply. That difference is the RTT. Operational use, flags and mtr are on ping and mtr; this page owns the mechanism.

host Ahost BEcho Request, type 8, id 7, seq 1Echo Reply, type 0, id 7, seq 1RTT = reply arrival time minus send time, measured at A
The identifier and sequence number travel unchanged to the target and back. The sender times the whole loop, so RTT includes the host's own ICMP handling, not only the wire.

Worked example: reading real ping output​

This is ping -c 4 8.8.8.8 on macOS (the per-reply lines are elided). The statistics line is the one to read:

PING 8.8.8.8 (8.8.8.8): 56 data bytes
64 bytes from 8.8.8.8: icmp_seq=0 ttl=116 time=...
...
--- 8.8.8.8 ping statistics ---
4 packets transmitted, 4 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 28.603/32.097/37.288/3.426 ms
  • 56 data bytes is the default payload. Add 8 bytes of ICMP header and each reply is 64 bytes, which is what ping prints. Add the 20-byte IPv4 header and the packet is 84 bytes on the wire (before the link-layer header).
  • ttl=116 is the TTL left in the reply when it arrived, not the TTL of your request. The remote host picked a starting value and every router on the return path subtracted 1. A start of 128 would mean 12 hops back. One number cannot prove that: the start value is a guess (see initial TTL by OS).
  • Loss 0.0% means every request got a reply. min/avg/max is the spread of RTTs, and stddev (called mdev on Linux) is the jitter: 3.4 ms on a 32 ms average is a steady path.

TTL is a hop limit​

Every IPv4 packet carries a Time To Live field (IP packet). The name is a historical leftover: it was meant to be seconds, but in practice every router subtracts exactly 1, so it is a hop count limit. A router that would take it to 0 drops the packet and sends Time Exceeded (type 11, code 0) to the source, quoting the dropped packet. TTL exists for loop protection: a packet in a routing loop dies instead of circulating forever. IPv6 renamed the field Hop Limit (IPv6) and its Time Exceeded is type 3. Traceroute turns this behaviour into a path-mapping tool; see traceroute for the traceroute half.

AR1R2BTTL 2TTL 1type 11, code 0TTL 0: dropThe error's source address is R2, so A learns who dropped it
A packet sent with TTL 2 survives R1 (2 becomes 1) and dies at R2 (1 would become 0). R2 returns type 11 code 0 with its own address as the source. Traceroute repeats this with TTL 1, 2, 3 and so on to name each hop.

Path MTU Discovery​

Links differ in MTU (MTU, MSS and fragmentation owns the depth). Hosts avoid fragmentation by setting DF (Don't Fragment) on every packet. A router that cannot forward a DF packet because the next link is too small drops it and returns ICMP type 3, code 4, Fragmentation Needed and DF Set. RFC 1191 puts the next-hop MTU in the low 16 bits of the otherwise unused word. The sender lowers its path MTU for that destination and resends in smaller packets.

SRDlink MTU 14001500 B, DF=1type 3, code 4, MTU 14001400 B, DF=1forwardedS caches 1400 as the path MTU for D
The 1500-byte packet with DF set cannot cross the 1400-byte link. R drops it and reports the limit. The sender resends 1400-byte packets, which fit.

IPv6 works the same way with one difference: routers never fragment IPv6 packets, so Packet Too Big (type 2, RFC 4443, RFC 8201) is mandatory, not an optimisation. It carries a 32-bit MTU field and is sent whenever a packet does not fit.

Deep dive​

Types and codes that matter​

The type names the message and the code refines it. Names below follow the IANA ICMP registry.

TypeName (IANA)Codes and notes
0Echo ReplyCode 0. The ping answer.
3Destination UnreachableCodes 0 to 15. See the next table.
5Redirect0 network, 1 host, 2 TOS and network, 3 TOS and host. A router tells a host a better first hop exists; hosts often ignore them today.
8EchoCode 0. IANA names it Echo; everyone says Echo Request.
11Time Exceeded0 TTL exceeded in transit, 1 fragment reassembly time exceeded. Code 0 powers traceroute.
12Parameter Problem0 pointer indicates the error, 1 missing a required option, 2 bad length.

Type 3 is the one with the long code list. The codes you meet in practice:

CodeIANA nameTypical cause
0Net UnreachableA router has no route to the destination network.
1Host UnreachableThe last-hop router got no ARP answer for the host.
2Protocol UnreachableThe host does not implement the IP protocol number.
3Port UnreachableNo socket on that UDP port. This is how traceroute knows it arrived.
4Fragmentation Needed and DF SetPath MTU Discovery. Carries the next-hop MTU.
9, 10Communication with Destination Network / Host is Administratively ProhibitedA filter said no (RFC 1122). Codes 6 and 7, destination network and host unknown, are also in the registry.
13Communication Administratively ProhibitedA router ACL or firewall rejected the packet (RFC 1812). Prefer it to a silent drop when you want fast failure.

The registry defines codes 0 to 15 for type 3. Type 4, Source Quench, once asked a sender to slow down and is deprecated (RFC 6633); congestion control lives in TCP now.

ICMPv6 (RFC 4443) has its own numbering, with errors below 128 and informational messages from 128:

TypeNameRole
1Destination UnreachableNo route, administratively prohibited, address unreachable, port unreachable.
2Packet Too BigThe IPv6 equivalent of type 3 code 4. Carries the MTU. Mandatory.
3Time ExceededCode 0 hop limit exceeded in transit, code 1 reassembly time exceeded.
4Parameter ProblemA header field or option was bad.
128 and 129Echo Request and Echo ReplyPing for IPv6.
133 to 137Router Solicitation, Router Advertisement, Neighbor Solicitation, Neighbor Advertisement, RedirectNeighbour discovery (RFC 4861). It replaces ARP, so IPv6 on a LAN does not work without it (IPv6, ARP).

The PMTUD black hole​

PMTUD fails silently when the ICMP message never reaches the sender. The usual cause is a firewall that drops all ICMP, so the Fragmentation Needed or Packet Too Big message is lost on the way back. The symptoms are a signature:

  • The TCP handshake works, because SYN and SYN-ACK are small.
  • Small requests and responses work. Anything that fills a full-size segment, such as a large HTTP response or a TLS certificate chain, hangs.
  • The sender keeps retransmitting a packet that is too big and never learns why.

Fixes, from best to worst:

  1. Allow the right ICMP: type 3 code 4 for IPv4 and type 2 for IPv6, in every direction a router might send it from. RFC 4890 lists which ICMPv6 types a firewall must pass.
  2. Clamp the MSS at the edge so TCP never builds packets that are too large. MSS clamping rewrites the MSS option in SYNs; the mechanism is in MTU, MSS and fragmentation.
  3. Use Packetization Layer PMTUD, which does not need ICMP: the sender probes with growing packet sizes and treats loss as the signal (RFC 4821, and the datagram version RFC 8899, which QUIC builds on). Linux enables it with net.ipv4.tcp_mtu_probing.

Initial TTL by OS​

The TTL a reply arrives with is the starting value minus the hops it crossed, so if you guess the starting value you can estimate the hops. Common starting values are 64 on Linux and macOS, 128 on Windows and 255 on many routers. On macOS sysctl net.inet.ip.ttl printed 64. The estimate is a heuristic: the value is configurable, and a reply of 116 from a far host could be 128 minus 12 or something else entirely. Do not treat it as OS fingerprinting evidence.

ICMP rate limiting​

Routers and hosts limit how many ICMP messages they originate. On Linux net.ipv4.icmp_ratelimit is the minimum gap between messages of the limited types in milliseconds (default 1000, kernel docs), and icmp_msgs_per_sec caps the host total. Routers apply control-plane policing for the same reason. Two consequences matter for reading output:

  • A router forwards traffic on its fast path but builds ICMP replies on a slow path, so a high RTT or loss at a middle hop in ping or mtr often says nothing about the traffic that passes through it. Loss only counts if it persists to the final hop (ping and mtr).
  • A PMTUD message can itself be rate limited, which makes a flaky black hole.

ICMP as an attack surface​

ICMP has been abused as an amplifier and a payload. Smurf sent a ping to a broadcast address with the victim's spoofed source, so every host replied to the victim. Networks fixed it by not forwarding directed broadcasts by default (RFC 2644). The ping of death exploited reassembly bugs with oversized fragmented echo requests, and hosts were patched. Today the live concerns are ICMP floods (DDoS), ICMP redirects used to divert traffic, and tunnelling data in echo payloads. The defence is selective filtering and rate limits, not blanket drops (firewalls and segmentation).

Textbook vs real world​

The textbook saysProduction doesWhy
Block ICMP for securityAllow type 3 code 4, ICMPv6 type 2 and neighbour discovery; rate-limit the restBlocking everything breaks Path MTU Discovery and IPv6 on the LAN
Ping failed, so the host is downA failed ping means no reply came backICMP may be filtered, rate limited or deprioritised while the service works fine
Ping measures network latencyIt measures network plus the target's ICMP handlingEcho is answered by the kernel or a slow control plane, which adds delay a TCP connection to the same host would not see
TTL is a time in secondsTTL is a hop countRouters subtract 1 per hop regardless of how long they held the packet

In production​

  • Cloudflare documented a real PMTUD failure: a networking change broke path MTU discovery on its servers and users on IPv6-over-IPv4 tunnels could not reach its services (Path MTU discovery in practice, 2015).
  • AWS security groups only allow inbound traffic you permit, so ICMP is not allowed by default. The EC2 documentation says an instance can receive Path MTU Discovery responses (Destination Unreachable, Fragmentation Needed and Don't Fragment was Set, type 3 code 4, for IPv4) when the connection is tracked or the security group allows inbound ICMP, and that a network ACL can still block them (EC2 network MTU).
  • Health checks choose between ICMP and TCP. An ICMP check says the host's network stack is up; a TCP or HTTP check says the service is. Use the one that matches what you are promising.

History and evolution​

HISTORY
  • 1981 RFC 792 defines ICMP, authored by Jon Postel, alongside the IP specification, because IP itself had no way to report delivery problems.
  • 1983 Mike Muuss writes ping at the Ballistic Research Laboratory and names it after sonar, by his own account (The Story of the PING Program).
  • 1990 Fragmentation made large transfers slow and fragile, so RFC 1191 defines Path MTU Discovery using type 3 code 4.
  • 1990s Ping of death and smurf attacks lead operators to filter ICMP wholesale, which in turn creates PMTUD black holes. RFC 4821 (2007) answers with probing that needs no ICMP.
  • 1998 to 2006 ICMPv6 is specified (RFC 2463, replaced by RFC 4443) and absorbs neighbour discovery.
  • Now ICMP is rate limited everywhere and ICMPv6 is essential. QUIC does its own datagram PMTU probing (RFC 8899).
  • Next More reliance on TCP and QUIC based probes and packetization-layer discovery, with ICMP kept as a hint.

Hands-on​

macOS:

ping -c 4 8.8.8.8
ping -D -s 1472 8.8.8.8
ping -D -s 1473 8.8.8.8

-D sets DF. On a 1500-byte link, -s 1472 plus 8 ICMP plus 20 IP is exactly 1500 and succeeds. One byte more fails at once with this real macOS output, because the local interface refuses:

ping: sendto: Message too long

Linux uses a different flag for the same test, and Windows differs again:

ping -c 4 8.8.8.8 # Linux
ping -M do -s 1472 8.8.8.8 # Linux: DF set, 1472 + 28 = 1500
ping -6 -c 4 2001:4860:4860::8888 # Linux IPv6 (macOS: ping6)
ping -n 4 8.8.8.8 # Windows

When a router further along the path has a smaller MTU, Linux ping (iputils) reports the type 3 code 4 message with the MTU it carried. The shape of the output is below, with an illustrative router address:

From 192.0.2.1 icmp_seq=1 Frag needed and DF set (mtu = 1400)

Binary-search the largest -s that passes to find the path MTU. To watch ICMP on the wire:

sudo tcpdump -n -i eth0 icmp

Look for the ICMP echo request and echo reply pairs, and for unreachable - need to frag (mtu 1400) lines. On Linux, ip route get <dst> shows the cached path MTU after a discovery.

Gotchas​

GOTCHAS5
Block ICMP to be safe
Ping works, so the service works
Ping times at hop 5 are high, so hop 5 is slow
TTL 64 means 64 seconds
ICMPv6 is optional

Interview questions​

INTERVIEWA user can connect to your site but large pages hang. Where do you look?senior
Show answer

Suspect a PMTUD black hole. The handshake and small responses fit in small packets; a full-size segment hits a link with a smaller MTU and the ICMP Fragmentation Needed message is filtered. Confirm with ping -M do -s 1472 and smaller sizes, and with a capture showing retransmitted full-size segments. Fix by allowing type 3 code 4 and ICMPv6 type 2, or clamp the MSS.

Follow-ups:

  • Why do small requests work? They fit under every link's MTU, so no router ever needs to send the error.
  • Why not just lower the MTU? You would have to do it on every host; clamping the MSS at the edge is the usual workaround.
INTERVIEWHow does ping work?junior
Show answer

Ping sends an ICMP Echo Request, type 8, with an identifier and sequence number. The target answers with an Echo Reply, type 0, copying them back. Ping measures the RTT as arrival time minus send time, and counts a request with no reply as lost.

Follow-ups:

  • Is there a port? No. ICMP has no ports and sits directly on IP, protocol 1.
  • What is in a default packet? 20 bytes IP, 8 bytes ICMP and 56 bytes payload, 84 in total.
INTERVIEWWhat is TTL, and what happens at zero?junior
Show answer

TTL is a hop limit in the IP header. Each router subtracts 1 and drops the packet when it would reach 0, sending ICMP Time Exceeded (type 11, code 0) to the source. It exists to stop packets circulating in routing loops.

Follow-ups:

  • Is it seconds? No, it is hops, whatever the name says.
  • What is it in IPv6? Hop Limit, with Time Exceeded as ICMPv6 type 3.
INTERVIEWExplain Path MTU Discovery.mid
Show answer

The sender sets DF. A router that cannot forward the packet drops it and returns ICMP type 3 code 4 with the next-hop MTU, and the sender retries with smaller packets. In IPv6 routers never fragment, so Packet Too Big, type 2, does the same job.

Follow-ups:

  • What breaks it? Any filter that drops those ICMP messages, producing a black hole.
  • Is there a way without ICMP? Packetization Layer PMTUD, RFC 4821 and RFC 8899.
INTERVIEWPing to a host fails, yet its website loads. Why?mid
Show answer

ICMP is separate from TCP. A firewall or cloud security group may drop Echo Requests while allowing port 443. A failed ping means no reply came back, not that the host is down.

Follow-ups:

  • How would you test reachability then? Connect to the real port.
  • Could the host be rate limiting? Yes, so a few lost pings are weak evidence.
INTERVIEWWhy can you not block ICMPv6 like ICMP?senior
Show answer

IPv6 depends on it. Neighbour discovery (types 133 to 137) replaces ARP, and Packet Too Big is the only way a sender learns the path MTU because routers do not fragment. RFC 4890 lists the types a firewall must allow.

Follow-ups:

  • What can be dropped? Echo can be filtered at the edge, and unneeded types rate limited.
INTERVIEWPing shows 30% loss at a middle hop but 0% at the destination. Is there a problem?mid
Show answer

Probably not. A router answers ICMP on a rate-limited slow path, so loss there is its own policing. If traffic reaches the destination without loss, forwarding is fine. Loss that continues from that hop to the end is real.

Follow-ups:

  • What would confirm it? The final hop's loss in mtr over many samples.

Fun facts​

FACTSTrivia worth knowing
  • IANA still lists type 8 as Echo, not Echo Request; the registry has codes 0 to 15 for Destination Unreachable.
  • Ping is named after sonar, per its author's own story, and a default ping is 84 bytes at the IP level.
  • ICMP has no port numbers. Ping uses an identifier field in place of a port to tell concurrent pings apart.
  • The next-hop MTU in a type 3 code 4 message did not exist in the original RFC 792, which is why very old routers send 0 and why RFC 1191 gives hosts a table of plateau sizes to guess from.

Cheat sheet​

NUMBERSNumbers to remember
  • Protocol 1 - ICMP in IPv4. IPv6 uses next header 58.
  • 8 and 0 - Echo Request and Echo Reply (ICMPv6: 128 and 129).
  • 11, code 0 - TTL exceeded in transit (ICMPv6: type 3).
  • 3, code 4 - Fragmentation Needed and DF Set (ICMPv6: type 2, Packet Too Big).
  • 84 bytes - default ping on the wire: 20 IP + 8 ICMP + 56 data.
  • 1472 - the largest ping payload that fits a 1500-byte MTU (1472 + 28).
  • 1280 bytes - the minimum IPv6 MTU (RFC 8200).
  • 64, 128, 255 - common initial TTLs: Linux and macOS, Windows, many routers.