Linux ping and traceroute Commands
last modified October 23, 2026
The ping command checks whether a host is reachable and
measures the round-trip time to it. The traceroute command
shows the routers that packets pass on the way to a host. Together they
are the first tools to reach for when a network connection is slow or does
not work at all.
ping sends ICMP echo request packets and waits for
echo reply packets. traceroute sends probes with an
increasing time-to-live (TTL) value and collects the ICMP time
exceeded messages that routers send back when the TTL runs out.
The examples were run on Debian 12 with iputils 20221126 (ping and
tracepath), traceroute 2.1.2, and mtr 0.95. Except for the first example,
they use a small lab network: the client machine reaches the
10.10.3.0/24 network through two routers, r1 and
r2. The link behind r1 adds about 5 ms of delay,
the link behind r2 about 12 ms. On the far network,
server is an ordinary host, web is a web server
whose firewall blocks ping and UDP, and flaky loses a quarter
of its packets.
client 10.10.1.10 | r1 10.10.1.1 / 10.10.2.1 | (5 ms) r2 10.10.2.2 / 10.10.3.1 | (12 ms, MTU 1400) server 10.10.3.10 web 10.10.3.20 flaky 10.10.3.30
Pinging a host on the Internet
In its simplest form, ping takes a host name or an IP
address.
ping -c 4 example.com
The -c 4 option sends four echo requests and stops. Each
reply line shows the size of the reply, the sender, the sequence number
icmp_seq, the TTL of the reply, and the round-trip time. The
summary shows how many packets were lost and the minimum, average, and
maximum round-trip times; mdev is the mean deviation, a
measure of jitter. The round-trip times on a home connection to the
Internet vary considerably, as the output shows.
$ ping -c 4 example.com PING example.com (104.20.23.154) 56(84) bytes of data. 64 bytes from 104.20.23.154 (104.20.23.154): icmp_seq=1 ttl=59 time=4.55 ms 64 bytes from 104.20.23.154 (104.20.23.154): icmp_seq=2 ttl=59 time=10.9 ms 64 bytes from 104.20.23.154 (104.20.23.154): icmp_seq=3 ttl=59 time=35.5 ms 64 bytes from 104.20.23.154 (104.20.23.154): icmp_seq=4 ttl=59 time=4.22 ms --- example.com ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3005ms rtt min/avg/max/mdev = 4.223/13.790/35.518/12.820 ms
Pinging a host in the lab
The same command against the server in the lab network.
ping -c 4 server
The round-trip time of about 17 ms is the sum of the delays on the path there and back. The TTL of the reply is 62: Linux sends packets with a TTL of 64, and each of the two routers decreased it by one. The TTL in the reply therefore hints at how many hops away a host is, as long as we know the initial value of its operating system (64 for Linux and macOS, 128 for Windows, 255 for many network devices).
$ ping -c 4 server PING server (10.10.3.10) 56(84) bytes of data. 64 bytes from server (10.10.3.10): icmp_seq=1 ttl=62 time=18.7 ms 64 bytes from server (10.10.3.10): icmp_seq=2 ttl=62 time=16.5 ms 64 bytes from server (10.10.3.10): icmp_seq=3 ttl=62 time=17.4 ms 64 bytes from server (10.10.3.10): icmp_seq=4 ttl=62 time=17.8 ms --- server ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3003ms rtt min/avg/max/mdev = 16.518/17.585/18.694/0.783 ms
Stopping ping with Ctrl+C
Without -c, Linux ping runs until it is
interrupted.
ping server echo $?
We pressed Ctrl+C after three replies; ^C marks the place.
ping catches the signal, prints the statistics, and exits
with status 0, because it received replies. On Windows, ping
stops after four packets by default; on Linux, use -c in
scripts, or it never finishes.
$ ping server PING server (10.10.3.10) 56(84) bytes of data. 64 bytes from server (10.10.3.10): icmp_seq=1 ttl=62 time=18.0 ms 64 bytes from server (10.10.3.10): icmp_seq=2 ttl=62 time=16.8 ms 64 bytes from server (10.10.3.10): icmp_seq=3 ttl=62 time=16.9 ms ^C --- server ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2001ms rtt min/avg/max/mdev = 16.832/17.229/17.961/0.518 ms $ echo $? 0
Names and numeric output
ping resolves the host name to an address and, for every
reply, the address back to a name.
cat /etc/hosts | grep 10.10 ping -c 2 10.10.3.10 ping -n -c 2 server
The lab names are defined in /etc/hosts. When we give a
numeric address, ping does not look up names at all. The
-n option prints numeric addresses even when a name was
given. Use it when the reverse lookups are slow, which happens when DNS
is broken, the very situation in which ping is usually
needed.
$ cat /etc/hosts | grep 10.10 10.10.1.1 r1 10.10.2.2 r2 10.10.3.10 server 10.10.3.20 web 10.10.3.30 flaky 10.10.1.10 client $ ping -c 2 10.10.3.10 PING 10.10.3.10 (10.10.3.10) 56(84) bytes of data. 64 bytes from 10.10.3.10: icmp_seq=1 ttl=62 time=18.2 ms 64 bytes from 10.10.3.10: icmp_seq=2 ttl=62 time=16.2 ms --- 10.10.3.10 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1001ms rtt min/avg/max/mdev = 16.239/17.214/18.190/0.975 ms $ ping -n -c 2 server PING server (10.10.3.10) 56(84) bytes of data. 64 bytes from 10.10.3.10: icmp_seq=1 ttl=62 time=16.2 ms 64 bytes from 10.10.3.10: icmp_seq=2 ttl=62 time=16.1 ms --- server ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1003ms rtt min/avg/max/mdev = 16.139/16.150/16.162/0.011 ms
Interval and quiet output
By default, ping sends one packet per second. The
-i option sets a different interval in seconds.
ping -c 5 -i 0.2 -q server ping -c 5 -i 0.001 server
Five packets with an interval of 0.2 seconds take 0.8 seconds. The
-q option (quiet) prints only the first line and the summary.
Ordinary users cannot send faster than once every 2 ms; smaller intervals
are only allowed for root.
$ ping -c 5 -i 0.2 -q server PING server (10.10.3.10) 56(84) bytes of data. --- server ping statistics --- 5 packets transmitted, 5 received, 0% packet loss, time 803ms rtt min/avg/max/mdev = 15.088/17.232/19.354/1.600 ms $ ping -c 5 -i 0.001 server PING server (10.10.3.10) 56(84) bytes of data. ping: cannot flood; minimal interval allowed for user is 2ms
Packet size
The -s option sets the number of data bytes in each echo
request. The default is 56.
ping -c 2 -s 1000 server ping -c 2 -s 0 server
The first line shows two sizes: 1000 data bytes, and 1028 bytes of the
whole IP packet, which adds an 8-byte ICMP header and a 20-byte IP
header. The replies show 1008 bytes, the ICMP part. With fewer than 16
data bytes, there is no room for the timestamp that ping
puts into each packet, so no round-trip times are shown.
$ ping -c 2 -s 1000 server PING server (10.10.3.10) 1000(1028) bytes of data. 1008 bytes from server (10.10.3.10): icmp_seq=1 ttl=62 time=18.7 ms 1008 bytes from server (10.10.3.10): icmp_seq=2 ttl=62 time=16.2 ms --- server ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1001ms rtt min/avg/max/mdev = 16.241/17.495/18.749/1.254 ms $ ping -c 2 -s 0 server PING server (10.10.3.10) 0(28) bytes of data. 8 bytes from server (10.10.3.10): icmp_seq=1 ttl=62 8 bytes from server (10.10.3.10): icmp_seq=2 ttl=62 --- server ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1001ms
Deadline and timeout
Two options limit how long ping runs. -w is a
deadline for the whole command, -W the time to wait for each
reply.
time ping -w 3 server time ping -c 2 -W 1 web
With -w 3, ping stops after three seconds
regardless of the number of packets. The web host drops echo
requests silently, so there are no replies at all, just 100% packet loss.
With -W 1, ping waits only one second for the
last reply instead of the default ten seconds.
$ time ping -w 3 server PING server (10.10.3.10) 56(84) bytes of data. 64 bytes from server (10.10.3.10): icmp_seq=1 ttl=62 time=16.2 ms 64 bytes from server (10.10.3.10): icmp_seq=2 ttl=62 time=19.3 ms 64 bytes from server (10.10.3.10): icmp_seq=3 ttl=62 time=17.9 ms --- server ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2003ms rtt min/avg/max/mdev = 16.243/17.827/19.335/1.263 ms real 0m3.003s user 0m0.000s sys 0m0.004s $ time ping -c 2 -W 1 web PING web (10.10.3.20) 56(84) bytes of data. --- web ping statistics --- 2 packets transmitted, 0 received, 100% packet loss, time 1004ms real 0m2.007s user 0m0.001s sys 0m0.002s
Error messages
Not every failure is silent. Routers report problems with ICMP error
messages, which ping prints.
ping -c 2 10.10.3.99 ping -c 1 192.0.2.1 ping -c 1 nosuchhost
No host has the address 10.10.3.99; the last router, r2,
tries to find it with ARP, gives up, and sends Destination Host
Unreachable. The address 192.0.2.1 is outside any network that the
routers know about; r2 has a route of type
unreachable for it and reports the same error. The
+2 errors in the statistics counts these messages. The last
command fails before sending anything, because the name cannot be
resolved.
$ ping -c 2 10.10.3.99 PING 10.10.3.99 (10.10.3.99) 56(84) bytes of data. From 10.10.2.2 icmp_seq=1 Destination Host Unreachable From 10.10.2.2 icmp_seq=2 Destination Host Unreachable --- 10.10.3.99 ping statistics --- 2 packets transmitted, 0 received, +2 errors, 100% packet loss, time 1046ms pipe 2 $ ping -c 1 192.0.2.1 PING 192.0.2.1 (192.0.2.1) 56(84) bytes of data. From 10.10.2.2 icmp_seq=1 Destination Host Unreachable --- 192.0.2.1 ping statistics --- 1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms $ ping -c 1 nosuchhost ping: nosuchhost: Temporary failure in name resolution
Exit status
ping reports the result in its exit status: 0 when at least
one reply arrived, 1 when no reply arrived, and 2 for other errors.
ping -c 1 -W 1 server > /dev/null; echo $? ping -c 1 -W 1 web > /dev/null; echo $? ping -c 1 -W 1 nosuchhost > /dev/null; echo $?
The error about the unknown name goes to standard error, so it is shown
despite the redirection. The exit status makes ping easy to
use in scripts.
$ ping -c 1 -W 1 server > /dev/null; echo $? 0 $ ping -c 1 -W 1 web > /dev/null; echo $? 1 $ ping -c 1 -W 1 nosuchhost > /dev/null; echo $? ping: nosuchhost: Temporary failure in name resolution 2
Checking hosts in a script
The following script checks a list of hosts.
cat check-hosts.sh bash check-hosts.sh
Each host gets one packet and one second to answer. The script reports
web as not responding, although the web server on it runs
fine: its firewall only blocks ping. A failed ping does not prove that a
host is down, and a successful ping does not prove that a service works;
see the section about firewalls below.
$ cat check-hosts.sh
#!/bin/bash
for host in r1 r2 server web flaky; do
if ping -c 1 -W 1 "$host" > /dev/null 2>&1; then
echo "$host is up"
else
echo "$host is not responding"
fi
done
$ bash check-hosts.sh
r1 is up
r2 is up
server is up
web is not responding
flaky is up
Time to live
The -t option sets the TTL of the outgoing packets. Every
router decreases the TTL by one and discards the packet when it reaches
zero, sending a Time to live exceeded message back.
ping -c 1 -t 1 server ping -c 1 -t 2 server ping -c 1 -t 3 server
With a TTL of 1, the packet dies at the first router, r1.
With 2, it dies at r2. With 3, it reaches the server. This is
exactly how traceroute discovers the path: it sends packets
with TTL 1, 2, 3, and so on, and records who reports the expired TTL.
$ ping -c 1 -t 1 server PING server (10.10.3.10) 56(84) bytes of data. From r1 (10.10.1.1) icmp_seq=1 Time to live exceeded --- server ping statistics --- 1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms $ ping -c 1 -t 2 server PING server (10.10.3.10) 56(84) bytes of data. From r2 (10.10.2.2) icmp_seq=1 Time to live exceeded --- server ping statistics --- 1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms $ ping -c 1 -t 3 server PING server (10.10.3.10) 56(84) bytes of data. 64 bytes from server (10.10.3.10): icmp_seq=1 ttl=62 time=19.2 ms --- server ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 19.224/19.224/19.224/0.000 ms
Packet loss
Packet loss is best measured with more packets. The flaky
host drops a quarter of its outgoing packets.
ping -c 20 -q flaky
Of 20 packets, 14 came back, so the measured loss is 30%. Losses are random, so a small sample only gives a rough estimate of the real rate. A few lost packets on a busy network are normal; consistent loss of several percent causes noticeable problems, especially for TCP throughput, voice, and video.
$ ping -c 20 -q flaky PING flaky (10.10.3.30) 56(84) bytes of data. --- flaky ping statistics --- 20 packets transmitted, 14 received, 30% packet loss, time 19158ms rtt min/avg/max/mdev = 14.629/16.991/19.414/1.333 ms
Timestamps and missing replies
The -D option prefixes each line with a Unix timestamp, which
is useful when ping runs for a long time and its output is logged. The
-O option reports requests that got no reply before the next
one is sent.
ping -c 3 -D server ping -c 6 -O -i 0.5 flaky
Without -O, a lost packet only shows up as a gap in the
icmp_seq numbers. With it, ping prints
no answer yet for icmp_seq=4. The timestamps can be converted
with date -d @1792783736.
$ ping -c 3 -D server PING server (10.10.3.10) 56(84) bytes of data. [1792784494.845978] 64 bytes from server (10.10.3.10): icmp_seq=1 ttl=62 time=17.3 ms [1792784495.848863] 64 bytes from server (10.10.3.10): icmp_seq=2 ttl=62 time=19.2 ms [1792784496.849858] 64 bytes from server (10.10.3.10): icmp_seq=3 ttl=62 time=19.3 ms --- server ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2002ms rtt min/avg/max/mdev = 17.316/18.599/19.270/0.907 ms $ ping -c 6 -O -i 0.5 flaky PING flaky (10.10.3.30) 56(84) bytes of data. 64 bytes from flaky (10.10.3.30): icmp_seq=1 ttl=62 time=16.2 ms 64 bytes from flaky (10.10.3.30): icmp_seq=2 ttl=62 time=18.7 ms 64 bytes from flaky (10.10.3.30): icmp_seq=3 ttl=62 time=16.6 ms no answer yet for icmp_seq=4 64 bytes from flaky (10.10.3.30): icmp_seq=5 ttl=62 time=16.7 ms 64 bytes from flaky (10.10.3.30): icmp_seq=6 ttl=62 time=18.5 ms --- flaky ping statistics --- 6 packets transmitted, 5 received, 16.6667% packet loss, time 2509ms rtt min/avg/max/mdev = 16.245/17.359/18.746/1.036 ms
Finding the path MTU
The maximum transmission unit (MTU) is the largest packet a link can
carry. The link between r2 and the server has an MTU of 1400
bytes, while the other links have the usual 1500. The -M do
option sets the Don't Fragment flag, so routers must not split the packet.
ping -c 2 -M do -s 1472 server ping -c 2 -M do -s 1372 server
1472 data bytes plus 28 bytes of headers make a 1500-byte packet.
r2 cannot forward it and reports Frag needed and DF
set with the MTU of the next link. The kernel remembers the path MTU
for the destination, so the second packet is refused locally with
message too long. With 1372 data bytes, the packet has 1400 bytes
and passes. Path MTU problems typically show up as connections that
establish but hang on larger transfers, for example with VPNs and
tunnels.
$ ping -c 2 -M do -s 1472 server PING server (10.10.3.10) 1472(1500) bytes of data. From r2 (10.10.2.2) icmp_seq=1 Frag needed and DF set (mtu = 1400) ping: local error: message too long, mtu=1400 --- server ping statistics --- 2 packets transmitted, 0 received, +2 errors, 100% packet loss, time 1001ms $ ping -c 2 -M do -s 1372 server PING server (10.10.3.10) 1372(1400) bytes of data. 1380 bytes from server (10.10.3.10): icmp_seq=1 ttl=62 time=16.7 ms 1380 bytes from server (10.10.3.10): icmp_seq=2 ttl=62 time=18.0 ms --- server ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1002ms rtt min/avg/max/mdev = 16.651/17.314/17.977/0.663 ms
Flood ping
The -f option sends packets as fast as replies come back, or
100 times per second, whichever is more. It is restricted to root.
ping -f -c 200 server sudo ping -f -c 200 server
For every request, ping prints a dot, and for every reply, it
removes one, so the number of dots shows how many requests are
outstanding. The summary adds ipg, the inter-packet gap, and
ewma, a moving average of the round-trip time. A flood ping
is a load test; use it only on networks you are responsible for.
$ ping -f -c 200 server PING server (10.10.3.10) 56(84) bytes of data. ping: cannot flood; minimal interval allowed for user is 2ms $ sudo ping -f -c 200 server PING server (10.10.3.10) 56(84) bytes of data. .. .. . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . .. . . . . . . .. .. . . . . . . . . . . . .. . . . . . . . . . . . . . . . .. .. .. .. .. .. .. . . . . . . . . . . . . .. . . .. . . . . . . . . . . . . . . . . .. .. .. .. . . . . . . . . . . . . .. .. . . . . . . . . . . . . . . . . . . . . . .. .. . . . . .. . . . . . . . . . . . . --- server ping statistics --- 200 packets transmitted, 200 received, 0% packet loss, time 2790ms rtt min/avg/max/mdev = 14.647/17.296/19.782/1.241 ms, pipe 2, ipg/ewma 14.021/17.402 ms
IPv6
The ping from iputils handles both IPv4 and IPv6. The
-4 and -6 options force one of them when a name
has both kinds of addresses.
ping -c 2 ::1 ping -6 -c 1 localhost
::1 is the IPv6 loopback address. Older systems have a
separate ping6 command for IPv6; on current distributions, it
is a link to ping or is missing.
$ ping -c 2 ::1 PING ::1(::1) 56 data bytes 64 bytes from ::1: icmp_seq=1 ttl=64 time=0.041 ms 64 bytes from ::1: icmp_seq=2 ttl=64 time=0.044 ms --- ::1 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1051ms rtt min/avg/max/mdev = 0.041/0.042/0.044/0.001 ms $ ping -6 -c 1 localhost PING localhost(localhost (::1)) 56 data bytes 64 bytes from localhost (::1): icmp_seq=1 ttl=64 time=0.029 ms --- localhost ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.029/0.029/0.029/0.000 ms
Tracing the route
The traceroute command shows every router on the path to a
host.
traceroute server
Each line is a hop: the router that sent back the time exceeded
message, and the round-trip times of three probes. By default,
traceroute on Linux sends UDP packets to high ports, starting
at 33434. The final host answers with port unreachable, which
tells traceroute that the destination is reached.
$ traceroute server traceroute to server (10.10.3.10), 30 hops max, 60 byte packets 1 r1 (10.10.1.1) 0.069 ms 0.017 ms 0.014 ms 2 r2 (10.10.2.2) 5.502 ms 4.327 ms 5.263 ms 3 server (10.10.3.10) 15.748 ms 16.764 ms 17.413 ms
Traceroute options
The -n option disables name lookups, -q sets the
number of probes per hop, and -m the maximum number of hops.
traceroute -n -q 1 server traceroute -m 2 server
With -m 2, the trace stops after the second hop. The
asterisks in its output are probes without an answer. They are not lost
packets: traceroute sends up to 16 probes at once, and the
Linux kernel limits how many ICMP error messages it sends per second, so
the routers did not answer every probe. Rate limiting like this is common
on the Internet, on routers and hosts alike. The -N option
lowers the number of simultaneous probes.
$ traceroute -n -q 1 server traceroute to server (10.10.3.10), 30 hops max, 60 byte packets 1 10.10.1.1 0.048 ms 2 10.10.2.2 5.712 ms 3 10.10.3.10 15.964 ms $ traceroute -m 2 server traceroute to server (10.10.3.10), 2 hops max, 60 byte packets 1 r1 (10.10.1.1) 0.052 ms 0.016 ms * 2 r2 (10.10.2.2) 5.501 ms 4.658 ms *
Firewalls and probe types
Many hosts and firewalls drop UDP probes and pings. The -I
option makes traceroute use ICMP echo requests, like
ping, and -T uses TCP SYN packets to a given
port. Both need root privileges.
traceroute -m 6 web sudo traceroute -I -m 6 web sudo traceroute -T -p 80 web nc -zv web 80
The firewall of web drops UDP and echo requests, so the
default trace and the ICMP trace end with lines of asterisks after the
second router. This looks like a network problem behind r2,
but it is not. A TCP probe to port 80, which the firewall allows, reaches
the host. To check a service, test the service itself; here,
nc -zv confirms that the web server accepts connections.
$ traceroute -m 6 web traceroute to web (10.10.3.20), 6 hops max, 60 byte packets 1 * * * 2 * * * 3 * * * 4 * * * 5 * * * 6 * * * $ sudo traceroute -I -m 6 web traceroute to web (10.10.3.20), 6 hops max, 60 byte packets 1 r1 (10.10.1.1) 0.227 ms 0.777 ms 0.787 ms 2 r2 (10.10.2.2) 5.685 ms 4.783 ms 5.684 ms 3 * * * 4 * * * 5 * * * 6 * * * $ sudo traceroute -T -p 80 web traceroute to web (10.10.3.20), 30 hops max, 60 byte packets 1 r1 (10.10.1.1) 0.049 ms 0.009 ms 0.007 ms 2 r2 (10.10.2.2) 4.601 ms 4.446 ms 4.463 ms 3 web (10.10.3.20) 16.155 ms 15.310 ms 17.852 ms $ nc -zv web 80 Connection to web (10.10.3.20) 80 port [tcp/http] succeeded!
The tracepath command
The tracepath command from iputils traces the route without
root privileges and also discovers the path MTU.
tracepath server tracepath -n -b server
The first line shows the MTU of the local interface, 1500 bytes. At hop 3,
r2 reports that the next link only carries 1400 bytes, and
tracepath continues with smaller probes; the
Resume line shows the MTU of the whole path. The kernel
remembers the discovered path MTU, so the second run starts with 1400
right away. -n prints addresses and -b both
names and addresses.
$ tracepath server
1?: [LOCALHOST] pmtu 1500
1: r1 0.051ms
1: r1 0.018ms
2: r2 5.029ms
3: r2 4.457ms pmtu 1400
3: server 17.037ms reached
Resume: pmtu 1400 hops 3 back 3
$ tracepath -n -b server
1?: [LOCALHOST] pmtu 1400
1: 10.10.1.1 (r1) 0.044ms
1: 10.10.1.1 (r1) 0.076ms
2: 10.10.2.2 (r2) 4.593ms
3: 10.10.3.10 (server) 17.834ms reached
Resume: pmtu 1400 hops 3 back 3
The mtr command
The mtr command combines traceroute and
ping: it traces the path and then keeps sending probes to all
hops, collecting statistics. Run without options, it shows a live,
full-screen view; the --report (-r) option runs a
fixed number of cycles and prints a table.
mtr --report -c 10 server mtr -r -n -c 20 flaky
The first report shows 20% loss at r1 but none at the hops
after it. Packets that reached the server passed through r1,
so the loss is not real; the router only limited its ICMP replies. Loss
matters only when it continues to the final hop, as in the second report,
where flaky loses 20% of the packets while the routers before
it lose none. This is the most common mistake when reading
mtr and traceroute output.
$ mtr --report -c 10 server Start: 2026-10-23T21:41:59+0200 HOST: client Loss% Snt Last Avg Best Wrst StDev 1.|-- r1 20.0% 10 0.1 0.1 0.0 0.1 0.0 2.|-- r2 0.0% 10 5.0 5.5 4.8 6.2 0.5 3.|-- server 0.0% 10 15.1 16.8 14.8 18.9 1.5 $ mtr -r -n -c 20 flaky Start: 2026-10-23T21:42:14+0200 HOST: client Loss% Snt Last Avg Best Wrst StDev 1.|-- 10.10.1.1 0.0% 20 0.1 0.1 0.0 0.1 0.0 2.|-- 10.10.2.2 0.0% 20 4.6 5.4 4.2 6.2 0.7 3.|-- 10.10.3.30 20.0% 20 18.5 18.0 16.5 19.6 0.9
Unreachable networks in traceroute
When a router reports an error, traceroute marks the probe
with an annotation after the time.
traceroute -n 192.0.2.1
!H means host unreachable. Other annotations are
!N (network unreachable), !P (protocol
unreachable), and !X (communication administratively
prohibited, typically a firewall that rejects the packet). The trace stops
at the router that reported the error.
$ traceroute -n 192.0.2.1 traceroute to 192.0.2.1 (192.0.2.1), 30 hops max, 60 byte packets 1 10.10.1.1 0.465 ms 0.377 ms 0.349 ms 2 10.10.2.2 4.282 ms !H 4.196 ms !H *
Troubleshooting with ping and traceroute
A common order of checks when a host cannot be reached:
- Ping the default gateway; if it does not answer, the problem is local (cable, Wi-Fi, address configuration). See the ip command.
- Ping a well-known IP address; if this works but names do not, the problem is DNS.
- Ping the target by name and by address.
- Trace the route to see where packets stop. Asterisks at the end may
mean a firewall rather than a broken network; try
-Twith the port of the service. - Test the service itself, for example with
nc -zvor curl.
Source
ping(8) manual page, traceroute(8) manual page
In this article, we have used ping to check reachability,
measure round-trip times, packet loss, and the path MTU, and
traceroute, tracepath, and mtr to
follow the path to a host, and we have seen how firewalls and ICMP rate
limiting affect their output. See also the
ss command article.
Author
List all Linux tutorials.