Debuggingpingicmpechorttpacket loss

ping: What an Echo Actually Proves

ping sends an ICMP echo request and reports whether a reply came back and how long it took; that answers "does this host respond to ICMP right now" and nothing else — a failed ping does not mean a service is down and a successful ping does not mean it is up.

ConceptualLinuxWindowsIPv6
Interview question
Progress

The problem

The runbook says "ping the server". It replies in 12 ms. The API is still returning connection refused. Or: ping gets no reply and the dashboard is green. What did the ping actually test?

What ICMP echo tests

ping builds an ICMP echo request (type 8) inside an IP packet, sends it to the destination, and waits for an echo reply (type 0). The reply is generated by the destination’s kernel — no process, no port, no listener is involved. So a reply proves exactly this: a route to the host exists in both directions, the host is powered on with a working IP stack, and nothing on the path filtered ICMP echo. Nothing else.

ICMP is not a transport. It has no ports, so it cannot address a service; it carries a sequence number and an identifier so that the sending ping can match replies to requests and detect loss and reordering. The round-trip time it reports is the time for a tiny packet — 64 bytes by default on Linux and macOS, 32 bytes of payload on Windows — to be routed there and back. It says nothing about bandwidth, and only a little about what a 100 kB HTTP response would experience.

That tiny scope is also what makes ping useful: because it needs nothing running on the far end, it is the cleanest test of the lower rungs of the Why Can’t I Connect? ladder — route and host — with no application in the way.

  • ICMP echo request = type 8, echo reply = type 0. Time Exceeded (type 11) and Destination Unreachable (type 3) are the other ICMP messages you will meet in traceroute: Discovering the Path Hop by Hop.
  • Replies come from the kernel; a host with every service crashed still answers.
  • Linux/macOS ping runs until interrupted; use -c 4. Windows sends four and stops; use -t for continuous.

A failed ping does not mean the service is down

Firewalls, cloud security groups and host firewalls routinely block ICMP echo while allowing TCP 443. AWS security groups have no ICMP rule by default; Windows Firewall blocks inbound echo by default on public profiles; many hardening guides drop ICMP wholesale. The result is a host that serves HTTPS flawlessly and never answers a ping. The correct reading of a failed ping is "ICMP echo is not reaching or not being answered", not "host down".

The confirmation is a probe at the layer you care about: nc -vz host 443, curl -sI https://host/, or Test-NetConnection host -Port 443. If the TCP probe connects, the host is up and the ping was filtered. If the TCP probe times out too, you now have two layers agreeing, which is much stronger evidence. The interview question "ping fails but the service works" is exactly this reasoning.

A rare inverse: ICMP is sometimes rate-limited rather than blocked, so a long ping shows sporadic loss that TCP never experiences. Routers and hosts cap ICMP generation on their control plane; a 2% ping loss to a router interface is normal, and means nothing about the data plane forwarding through it.

  • An explicit Destination host unreachable or communication administratively prohibited reply means a router or firewall rejected it; pure silence means dropped, or the host is off.
  • Locally, Destination Host Unreachable from your own IP usually means ARP/ND for the next hop failed — the gateway did not answer — see ARP and Neighbor Discovery: From an IP to a Local MAC.

A successful ping does not mean the service works

The reply is generated a few layers below any process. A server whose application crashed, whose listener is bound to 127.0.0.1, whose certificate expired last night, or whose disk is full still returns pings in 12 ms. Ping proves "host up", and "host up" is the fourth rung of a nine-rung ladder. The remaining five — port, handshake, TLS, HTTP, application — need their own tests, and each of them can fail with a perfect ping.

This is why production health checks are HTTP requests to a real endpoint, not pings. A load balancer that pinged its backends would happily send traffic to a machine whose web server was dead.

Reading the output: RTT, loss, jitter

Linux

Each reply line carries the sequence number, the TTL of the reply (which hints at hop count: 64 − 54 = about 10 hops if the far end started at 64), and the RTT. The summary gives sent, received, loss percentage, and min/avg/max/mdev. mdev (standard deviation of RTT) is jitter; a low average with a high mdev means an unstable path or a congested queue somewhere — bad for real-time traffic even if the average looks fine. Missing sequence numbers are loss; the summary percentage is the headline.

Calibrate the RTT against geography: ~1 ms on a LAN, ~10–30 ms within a region, ~80 ms across a continent, ~150 ms transatlantic, ~250 ms+ to the antipodes, 600 ms via geostationary satellite. An RTT far above the geographic floor means a detour or a queue — Latency: Same Machine to Cross-Continent lets you build the intuition. Loss above ~1% on a wired path is abnormal and will cripple TCP throughput (Packet Loss: Duplicate ACKs, Fast Retransmit and the RTO).

  • icmp_seq gaps = loss; mdev = jitter; ttl hints at the hop count from the reply’s starting TTL (64 for Linux/macOS, 128 for Windows, 255 for many routers).
  • ping -s 1472 -M do host (Linux) sends a full 1500-byte frame with fragmentation forbidden — the MTU test behind the MTU black-hole challenge. macOS: ping -D -s 1472; Windows: ping -f -l 1472.
Linux ping: one lost reply, moderate jitter; Windows format shown below for comparison
$ ping -c 5 api.example.com
PING api.example.com (203.0.113.10) 56(84) bytes of data.
64 bytes from 203.0.113.10: icmp_seq=1 ttl=54 time=12.1 ms
64 bytes from 203.0.113.10: icmp_seq=2 ttl=54 time=11.9 ms
64 bytes from 203.0.113.10: icmp_seq=4 ttl=54 time=41.7 ms
64 bytes from 203.0.113.10: icmp_seq=5 ttl=54 time=12.3 ms

--- api.example.com ping statistics ---
5 packets transmitted, 4 received, 20% packet loss, time 4006ms
rtt min/avg/max/mdev = 11.900/19.500/41.700/12.820 ms

C:\> ping api.example.com
Reply from 203.0.113.10: bytes=32 time=12ms TTL=54
Request timed out.
Ping statistics for 203.0.113.10: Sent = 4, Received = 3, Lost = 1 (25% loss)

IPv6: ping6 and why ICMPv6 must not be blocked wholesale

IPv6

On IPv6 the tool is ping -6 or ping6 (macOS and older Linux), and the messages are ICMPv6 echo request (type 128) and reply (type 129). The important difference is what else ICMPv6 carries: neighbor discovery (the IPv6 replacement for ARP), router advertisements, and Packet Too Big — the message path-MTU discovery depends on, and which is mandatory in IPv6 because routers never fragment. A firewall that "blocks ICMP" on IPv6 the way it did on IPv4 breaks address resolution and MTU discovery, not just ping. RFC 4890 lists which ICMPv6 types must pass.

Practically: if a dual-stack host resolves to an AAAA record and IPv6 is half-configured on the client, the browser may spend seconds timing out on IPv6 before falling back (Happy Eyeballs limits this to a few hundred milliseconds in modern stacks, but curl and older clients may not). ping -6 and ping -4 separately tell you which family is actually broken.

  • ping -6 host / ping6 host; ping -4 forces IPv4 on a dual-stack name.
  • ICMPv6 echo is type 128/129; Packet Too Big is type 2 and must be allowed through firewalls.

Key points

  • ping tests ICMP echo answered by the destination kernel: route both ways, host up, ICMP not filtered. Nothing about ports or services.
  • A failed ping is inconclusive — probe TCP on the real port before calling a host down.
  • A successful ping proves only "host up"; five rungs of the ladder remain above it.
  • Read RTT against geography, mdev as jitter, and sequence gaps as loss; loss above ~1% on a wired path is abnormal.
  • On IPv6, ICMPv6 also carries neighbor discovery and Packet Too Big; blocking it wholesale breaks more than ping.

Why does this exist?

Mechanisms are answers to constraints. Open each question before reading the answer.

Why does ping not use a port?

It is deliberately below the transport layer so it can test reachability without depending on any service. That independence is the feature; the price is that it cannot say anything about services.

Why do operators block ICMP echo?

Reconnaissance: an answered ping confirms a live host. The security gain is small, but the habit is widespread, so debugging must assume a silent ping may be a filtered one.

Why is ping still worth running first?

It is the cheapest test of route and host, needs nothing on the far end, and its RTT calibrates every later timing. A 150 ms ping explains a "slow" API before you look at the API.

How it fails

What the failure looks like from inside real software.

  • Alerting on ping and paging at 3 a.m. because a firewall rule changed, while every real request succeeded.
  • Marking a host healthy from a ping while its web server has been dead for an hour.
  • Reading 2% ping loss to a router hop as path loss, when the router merely rate-limits ICMP generation on its CPU.
  • Blocking all ICMPv6 "for security" and breaking neighbor discovery and path-MTU discovery on the IPv6 side.
  • Comparing a Windows time=12ms with a Linux time=12.1 ms and missing that payload sizes differ (32 vs 56 bytes) — harmless here, but not for MTU tests.