When you run ping, or when a router tells your computer “I have no route to that network”, the message is carried by ICMP. It is one of the smallest protocols on the internet, but network engineers use it every day.
What ICMP is
ICMP (Internet Control Message Protocol) is a helper protocol for IP. It doesn't carry web pages, files or email. It carries short control messages about the network itself. There are two kinds:
Queries (tests)
A device asks a question and expects an answer. The best-known one is echo request / echo reply, used by ping.
Error reports
A router or host tells the sender that its packet could not be delivered, and why: no route, TTL expired, port closed, and so on.
Why ICMP exists
IP is a best-effort protocol. It sends packets but has no built-in way to say “that didn't work”. Without feedback, a packet that hits a dead end would simply disappear, and the sender would keep waiting without knowing why. ICMP fills that gap:
- It reports problems back to the sender, so the sender can give up quickly or try something else.
- It gives engineers test tools: ping checks whether a device answers, and traceroute shows the path.
- It helps the network tune itself, for example by telling a sender that its packets are too big for a link.
💡 In simple terms: if IP is the postal service, ICMP is the small “returned to sender” note stuck on a letter that couldn't be delivered. It is also the “please confirm you received this” card that you can send on purpose.
Where ICMP sits
ICMP belongs to the network layer (Layer 3) together with IP, and every IP device must support it. But it travels inside an IP packet, just as TCP and UDP do. The Protocol field in the IP header says what the packet carries:
So on an Ethernet link, an ICMP message is wrapped like this: Ethernet header → IP header (protocol 1) → ICMP header → ICMP data. There is no TCP or UDP header in between, and therefore no port numbers. You can't ping “port 443”: ping talks to the device's IP stack (its operating system), not to an application.
Learn more: Port Numbers and Sockets
The ICMP header
Every ICMP message starts with the same three fields. The rest of the message depends on its type. Here is the layout of an echo request or echo reply:
| Field | What it means |
|---|---|
| Type | The kind of message, for example 8 = echo request, 3 = destination unreachable |
| Code | More detail within that type, for example type 3 code 1 = host unreachable |
| Checksum | Lets the receiver detect a damaged message |
| Rest of the message | For echo: identifier, sequence number and data. For errors: the IP header and first 8 bytes of data from the packet that caused the error |
The message types you need to know
| Type | Name | Kind | Used for |
|---|---|---|---|
0 | Echo reply | Query | The answer to a ping |
3 | Destination unreachable | Error | A packet could not be delivered (see the codes below) |
5 | Redirect | Error | A router tells a host that a better gateway for this destination is on its local network |
8 | Echo request | Query | The question ping sends: “Are you there?” |
11 | Time exceeded | Error | A router dropped the packet because its TTL reached 0 (traceroute relies on this) |
12 | Parameter problem | Error | A field in the IP header was invalid |
Echo request and echo reply (types 8 and 0)
This is how ping works, step by step:
- The ping program builds an ICMP echo request (type 8, code 0) with an identifier, a sequence number (starting at 1) and some filler data.
- The request is placed in an IP packet with protocol 1, the sender's IP address as the source and the target's IP address as the destination. It is sent like any other packet: directly to the target if it is on the local subnet, otherwise to the default gateway.
- Routers forward it hop by hop, lowering the TTL by 1 each time.
- The target's operating system receives it and answers with an echo reply (type 0, code 0), copying the identifier, sequence number and data.
- The reply travels back. The ping program matches it to the request by identifier and sequence number, and shows the round-trip time.
Error reporting: how routers say “that didn't work”
When a router or host has to drop a packet, it usually sends an ICMP error back to the packet's source IP address. The error includes a copy of the original IP header plus the first 8 bytes that followed it (enough to hold the TCP or UDP port numbers). This way, the sender can tell exactly which of its packets failed, and which application sent it.
- 1. Echo: a normal ping. The echo request reaches the server, and an echo reply comes back.
- 2. Net unreachable: a packet for 10.99.0.5 reaches R2, which has no route to that network. R2 drops it and sends type 3, code 0 back to 192.168.1.20.
- 3. Time exceeded: a packet arrives at R1 with TTL 1. R1 lowers it to 0, drops the packet and sends type 11 back. Traceroute relies on exactly this.
- 4. Port unreachable: a UDP datagram reaches the server, but no application is listening on that port. The server itself replies with type 3, code 3.
Destination unreachable (type 3)
The code tells you why the packet couldn't be delivered, and the device that sent the message tells you where it failed:
| Code | Name | Sent by | Meaning |
|---|---|---|---|
0 | Net unreachable | A router | It has no route to the destination network. |
1 | Host unreachable | The last router | The network exists, but the host didn't answer ARP. It may be switched off, or the address may be unused. |
3 | Port unreachable | The destination host | The packet arrived, but no application is listening on that UDP port. |
4 | Fragmentation needed | A router | The packet is too big for the next link and is marked “don't fragment”. Path MTU discovery relies on this message. |
13 | Administratively prohibited | A router or firewall | A filter (an access list) blocked the packet on purpose. |
Time exceeded (type 11)
Every IP packet has a TTL (time to live) field. Each router lowers it by 1, and a router that brings it to 0 must drop the packet. This stops packets from looping forever if routes are wrong. The router then sends an ICMP time exceeded message (type 11, code 0: “TTL exceeded in transit”) back to the source. Code 1 means something different: a host gave up waiting for all the fragments of a fragmented packet to arrive.
Traceroute turns this safety feature into a tool. It sends packets with TTL 1, then 2, then 3, and so on. Each router that answers with time exceeded reveals its address.
Rules that stop ICMP storms
- No ICMP error is sent about another ICMP error. Otherwise, two devices could bounce errors back and forth forever.
- No error is sent about a broadcast or multicast packet. Otherwise, one packet could trigger hundreds of replies.
- Routers rate-limit the ICMP messages they generate, so a flood of bad packets can't overload the router.
Packet behaviour: what you would see in a capture
A packet capture shows ICMP clearly. Here is one ping and one error, captured on the laptop with tcpdump. Wireshark shows the same packets with the display filter icmp:
$ sudo tcpdump -n -i eth0 icmp tcpdump: verbose output suppressed, use -v[v]... for full protocol decode listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes 10:21:04.118204 IP 192.168.1.20 > 203.0.113.10: ICMP echo request, id 3121, seq 1, length 64 10:21:04.142671 IP 203.0.113.10 > 192.168.1.20: ICMP echo reply, id 3121, seq 1, length 64 10:21:09.530118 IP 192.168.1.20 > 10.99.0.5: ICMP echo request, id 3122, seq 1, length 64 10:21:09.531007 IP 192.168.1.1 > 192.168.1.20: ICMP net 10.99.0.5 unreachable, length 92
id 3121, seq 1, with no port numbers anywhere. In the last two lines, the default gateway 192.168.1.1, not the target, reports that it has no route to 10.99.0.5. The error comes from the router and goes back to the original sender.| Field | Echo request | Net unreachable error |
|---|---|---|
| Source IP | 192.168.1.20 (laptop) | 192.168.1.1 (the router that gave up) |
| Destination IP | 10.99.0.5 | 192.168.1.20 (the original sender) |
| IP protocol | 1 | 1 |
| ICMP type / code | 8 / 0 | 3 / 0 |
| ICMP data | Filler bytes | The original IP header and the first 8 bytes of the echo request |
A real-world example
A user says the VPN connects, but some web pages stop half-loaded. Small pages work; large ones freeze. The cause is often blocked ICMP.
The VPN adds extra headers, so full-size packets are now too big for one link on the path. The router before that link drops them and sends ICMP type 3, code 4 (“fragmentation needed”) to tell the server to send smaller packets. But a firewall on the way blocks all ICMP, so the server never receives the message. It keeps resending large packets that disappear.
Engineers call this a PMTUD black hole. PMTUD (path MTU discovery) is the process of finding the largest packet size that fits the whole path. Allowing ICMP type 3 through the firewall fixes the problem.
Why some networks block ICMP
Many firewalls drop some or all ICMP, especially from the internet. The reasons are real, but the blocking often goes too far:
| Reason given | The catch |
|---|---|
| Echo replies let attackers find which addresses are in use (a “ping sweep”) | Fair for echo from the internet, but attackers can probe TCP ports just as easily |
| ICMP floods can be used for denial-of-service attacks | Rate limiting handles this without blocking everything |
| Error messages reveal internal router addresses | They also make troubleshooting possible |
💡 A sensible policy: allow echo request and echo reply at least from your own networks, always allow destination unreachable (especially “fragmentation needed”) and time exceeded, and rate-limit the rest.
Learn more: Firewall Basics
When ICMP fails, and what it tells you
Because ICMP is the messenger, a “failure” usually means a missing message. The key skill is telling the difference between silence and an answer:
| What ping shows | What happened | Where to look |
|---|---|---|
| Replies | The echo request and the echo reply both arrived | Nowhere: the path works in both directions |
| Timeout (silence) | No reply and no error came back | Target down, ICMP filtered, or no route for the reply to come back |
| “Destination net unreachable” from a router | That router sent type 3 code 0 | The routing table of the router named in the message |
| “Destination host unreachable” | The last router (or your own PC) got no ARP reply from the host | Is the host switched on, and in the right subnet? |
| “TTL expired in transit” | A router sent type 11 | Often a routing loop: packets circle until the TTL reaches 0 |
| “Communication administratively prohibited” | A filter rejected the packet and reported it | The access list or firewall on the reporting device |
$ ping -c 3 10.99.0.5 PING 10.99.0.5 (10.99.0.5) 56(84) bytes of data. From 192.168.1.1 icmp_seq=1 Destination Net Unreachable From 192.168.1.1 icmp_seq=2 Destination Net Unreachable From 192.168.1.1 icmp_seq=3 Destination Net Unreachable --- 10.99.0.5 ping statistics --- 3 packets transmitted, 0 received, +3 errors, 100% packet loss, time 2004ms
From 192.168.1.1 tells you which device sent the error: the default gateway. Its routing table has no route towards 10.99.0.5. +3 errors means an ICMP error came back for every request, which is different from a silent timeout. In 56(84) bytes, 56 bytes of data plus the 8-byte ICMP header plus the 20-byte IP header make 84 bytes.The next lessons explain the two tools that read ICMP, step by step.
Learn more: PingTraceroute
A note on ICMPv6
IPv6 has its own version, ICMPv6 (IPv6 next header 58). Echo request and echo reply become types 128 and 129, and the error messages work in a similar way. But ICMPv6 does much more than ICMP for IPv4. It carries Neighbor Discovery, which replaces ARP, and the router advertisements that tell hosts their default gateway and prefix. If you block ICMPv6 completely, IPv6 stops working.
Common mistakes
- Assuming a failed ping means the host is down. The host or a firewall may simply ignore echo requests. Test the real service too: for a website, open it in a browser or check TCP port 443.
- Thinking ICMP uses ports or runs over TCP or UDP. It sits directly inside IP as protocol 1, with a type and a code instead of ports.
- Ignoring which device sent the error. An unreachable message from a router points to a problem at that router, not at the target.
- Blocking every ICMP type on a firewall. It breaks path MTU discovery and makes troubleshooting much harder.
- Mixing up the type numbers. Echo request is 8 and echo reply is 0. Destination unreachable is 3 and time exceeded is 11.
- ICMP carries IP's test and error messages. It travels inside IP as protocol 1 and has no ports.
- Ping uses echo request (type 8) and echo reply (type 0).
- Destination unreachable (type 3) reports that a packet wasn't delivered; the code gives the reason.
- Time exceeded (type 11) is sent when the TTL reaches 0. Traceroute uses it to find each hop.
- Errors come from the device that dropped the packet and go back to the original sender.
- Filter ICMP carefully; don't block it completely. With IPv6, ICMPv6 is essential.
Check yourself
You run ping 203.0.113.10. Which IP protocol number and port does the ICMP echo request use?
A router receives a packet with TTL 1 that it needs to forward to another network. What does it do?
Your ping shows 'From 198.51.100.1: Destination Net Unreachable'. Where should you look first?
You send a UDP datagram to a server port where nothing is listening. Which ICMP message comes back (if it isn't filtered)?