Skip to main content

Traceroute on Mac, iPhone and iPad: find where the route breaks

A real ICMP traceroute on Mac, iPhone and iPad, streamed hop by hop, plus the part nobody explains: how to read what comes back.

By Lucas Russo, developer of SSHive · Updated

A service is slow or unreachable and nothing on your side explains it. DNS resolves, the server answers locally, your link is clean. What you cannot see is the fifteen or twenty routers between your machine and that host, and that is usually where the answer is. Traceroute is the tool that makes those routers visible. It does not measure your connection to a server; it reconstructs the sequence of hops your packets take to reach it and how long each one takes to answer. Read properly, it tells you whether a problem is yours, your ISP's, a transit provider's or the destination's: the difference between fixing something and opening a ticket with the right party. Read carelessly, it produces more wrong conclusions than any other network tool. A hop full of asterisks looks like a dead router and almost never is. A 300 ms spike in the middle of the path looks alarming when it is usually a router deprioritising your probe while forwarding production traffic without a hiccup. Reading a traceroute is mostly about knowing which lines are measurements and which lines are noise. SSHive measures a real traceroute on every Apple platform it ships on: the Mac App Store build, iPhone and iPad. It sends its own ICMP probes, one TTL value at a time, three probes per hop, up to thirty hops, and streams each router's address and timings back as they arrive. Nothing is reformatted and nothing is invented. That is worth saying plainly, because an earlier version of this page said the opposite. The claim was that a sandboxed App Store app cannot traceroute, since it would need raw ICMP sockets. It was never measured, and it is wrong: setting IP_TTL and reading the Time Exceeded replies works from an ordinary datagram ICMP socket, which needs no root and which the App Sandbox permits. Everything below explains the mechanism, and how to read the output.

What SSHive does

Its own probes, not the system binary

SSHive builds the probes itself rather than shelling out, so the same engine runs in the Mac App Store build, on iPhone and on iPad. One TTL value per hop, three probes each, up to thirty hops, with the router's address and its three round-trip times on every line. Nothing is synthesised and no third-party service sits in the middle: the packets leave your device and the replies come back to it.

Live output, hop by hop

Hops appear as they answer, streamed line by line into a monospace pane that scrolls itself. A Running badge shows the trace is still in flight, and Stop cancels it immediately, useful when a path stalls on a filtered hop and you already got your answer at hop 6. You never have to sit through a full 30-hop run.

The same trace on iPhone and iPad

The iOS and iPadOS apps run the same ICMP engine as the Mac, with the same thirty-hop ceiling and the same three probes per hop, so a trace started on your phone is directly comparable with one started on your Mac. That matters more than it sounds: tracing from the cellular network and from your office Wi-Fi to the same host is often what tells you whose network is at fault.

Disabled where it cannot work, never faked

When the system refuses ICMP outright (some corporate networks and a few VPN configurations do), SSHive stops and says so rather than printing a plausible-looking list of hops. A refusal is reported as a refusal. The same goes for a hop that never answers: it renders as asterisks, which is a real and common result, not an error.

Trace, then connect

A traceroute usually ends with a question: what is that last responding router, and can I get onto the machine behind it? SSHive is an SSH, SFTP, RDP and VNC client first, so the answer is one tab away. Identify the last good hop, open a session to the jump host or the server, and keep working in the same window.

Free, with no account

The whole network-tools suite (traceroute, ping, DNS lookup, whois, MX lookup and DNSBL checks) sits in the free tier on every platform where it is available. No feature gate on any of them, no ads, no sign-up. SSHive Pro is a one-time Universal Purchase across Mac, iPhone and iPad, and it unlocks session features, not diagnostics.

How to do it, step by step

  1. 1

    Open the network tools

    On the Mac, click the network icon in the sidebar, or the Network Tools button on the Welcome screen. Either one opens a dedicated tools tab alongside your sessions, so you can trace a route without closing what you are working in. On iPhone and iPad, the same tools live in the Tools tab.

  2. 2

    Find the Traceroute card

    The tools panel groups its cards into three sections, and you can move or hide cards within a section to keep only the tools you actually use. Traceroute is the last card of the Reachability section, after Ping and Port check.

  3. 3

    Enter a destination and start the trace

    Type a hostname or IP address in the field (the placeholder shows e.g. google.com) and press Trace. SSHive resolves it, then starts probing with a TTL of 1 and walks outward one hop at a time, up to 30.

  4. 4

    Watch the hops arrive

    Lines stream in as each router answers, with a Running badge while the trace is active. A hop showing asterisks is simply not replying inside the timeout, and the trace moves on to the next TTL. Press Stop as soon as you have seen what you needed.

  5. 5

    Act on the last responding hop

    Note the last hop that answered and whether the destination replied at all. From there, open an SSH, RDP or VNC session to the relevant host in the same window, or cross-check the target with the Ping and DNS Lookup cards above.

Reading a traceroute without reaching the wrong conclusion

Each line is one TTL value, not a measurement of your connection. Three probes go out per hop, so you get three round-trip times, and the spread matters as much as the values: 10 / 11 / 10 ms is a stable router, while 10 / 400 / 11 ms is one probe that got queued behind something and rarely deserves investigation. Every RTT includes a return path you never see. Hop 8's reply comes back over whatever route that router has toward you, which is often not the reverse of the outbound path. That is why hop 8 can read 90 ms while hop 9 reads 40 ms. It is not an error and latency did not drop: hop 8's reply simply took a slower way home. Never subtract two adjacent hops and call the result the latency of that link. Asterisks are the most misread output in networking. Three of them mean no ICMP Time Exceeded came back before the timeout (five seconds by default on macOS). There are three ordinary causes: the router does not generate ICMP errors at all, which is normal in ISP and MPLS cores; it rate-limits ICMP error generation, so it drops your probe's reply while forwarding production traffic perfectly; or a firewall blocks the outbound probe (macOS uses UDP from port 33434 upward) or the returning ICMP. In all three cases the data plane is healthy. The test is simple: if any hop after the asterisks answers, the silent hop forwarded your packet correctly. Only asterisks running unbroken to the end of the trace tell you anything. The same discipline applies to spikes. One hop at 300 ms between neighbours at 40 ms is a control-plane artefact: that router deprioritised your probe. What matters is whether an increase persists through every later hop and into the destination. A step that carries to the end is real, though it may be geography rather than a fault: a transatlantic leg costs its 70 to 90 ms and always will. Where a route genuinely breaks is the last hop that answered: the last router with both a route toward your target and a route back to you. If nothing after it replies and the destination never does either, the failure sits at or just past that point. A repeating pattern of the same hops is a routing loop. And !H, !N, !P or !X are definitive where asterisks are not: a router explicitly reporting the host, network or protocol unreachable, or the path administratively filtered.

Frequently asked questions

Does traceroute really work in the sandboxed Mac App Store build?+
Yes, with nothing held back. The common belief that it cannot is based on a confusion between two kinds of socket. Traceroute needs to set IP_TTL on outgoing probes and read the ICMP Time Exceeded replies routers send back. A raw socket would indeed be refused by the App Sandbox, but a datagram ICMP socket does both, needs no root, and is permitted. Measured under sandbox-exec with the app's own entitlements: setsockopt(IP_TTL) succeeds and the hops come back, router by router. One caveat found the hard way: com.apple.security.network.client alone is not enough, because the replies are then refused with EPERM; network.server is required as well, and SSHive declares both.
Can I run a traceroute from an iPhone or iPad?+
Yes, and it is a genuine measurement rather than an illustration. iOS allows no subprocess spawning and has no setuid binaries, so an app cannot simply call the system traceroute, which is why this is often assumed to be impossible. But the constraint is only on Network.framework, Apple's high-level API, which has no ICMP transport. Beneath it the BSD socket layer is intact: SSHive opens socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP), sets IP_TTL on each probe and reads the Time Exceeded replies, exactly as it does on the Mac. Thirty hops, three probes each. Tracing the same host from cellular and from Wi-Fi is often the quickest way to establish whose network is at fault.
What do three asterisks mean in a traceroute?+
That none of the three probes for that TTL got an ICMP Time Exceeded back before the timeout. It usually means the router is configured not to emit ICMP errors, is rate-limiting them, or that a firewall dropped the probe or the reply. It rarely means the router is broken. If any later hop answers, that silent router forwarded your packet perfectly. Only asterisks that continue unbroken to the end of the trace are a real signal.
Why does a middle hop show 300 ms when the destination shows 40 ms?+
Because answering your probe is not that router's job. Generating an ICMP Time Exceeded is control-plane work, handled by a CPU that deliberately gives it low priority, while the traffic it forwards stays on the fast path. A spike that does not propagate to the following hops is an artefact, not a fault. Only an increase that persists through every subsequent hop and into the destination reflects something the traffic actually experiences.
The trace stops at hop 12 and never reaches the host. Is the network down?+
Not necessarily. Plenty of destinations behind load balancers, anycast front-ends or cloud firewalls silently drop traceroute probes while serving TCP traffic normally, so a trace that dies near the end while the service works is expected. Confirm with a connectivity test to the real port (the TCP engine of Ping does exactly that) before concluding anything. If the service is genuinely unreachable, hop 12 is your evidence: it is the last router that had a route to your target and a route back to you, so the break sits at or immediately after it.
Can I change the hop limit, or probe with UDP instead of ICMP?+
Not from the SSHive card. The trace runs with a fixed 30-hop ceiling, ICMP probes and three probes per hop, with no protocol, port or probe-count options exposed, and no ASN or geolocation enrichment. If you need those switches on a Mac, /usr/sbin/traceroute accepts them directly in Terminal; the card is there for the common case of tracing a host fast without leaving your sessions, and for iPhone and iPad, where there is no Terminal to fall back on.
Is traceroute part of SSHive Pro?+
No. Traceroute and the rest of the network-tools suite are free on every platform, with no feature gate, no ads and no account to create. SSHive Pro is a one-time Universal Purchase across Mac, iPhone and iPad, with no subscription; it unlocks session-side capabilities rather than diagnostics.

TTL, ICMP errors, and how a sandboxed app does this anyway

An IPv4 header carries an 8-bit TTL field (IPv6 calls it Hop Limit) whose only purpose is to stop packets circulating forever. Every router that forwards a packet decrements it by one; when it reaches zero the router discards the packet and returns an ICMP Time Exceeded message, type 11 code 0, sourced from the interface the packet arrived on. Traceroute turns that failure mode into a measurement. It sends a probe with TTL 1, which dies at the first router and elicits an error naming it. Then TTL 2, then TTL 3, walking outward one hop at a time. Three probes per TTL produce the three timings on each line. How the target is recognised depends on the probe type: the BSD traceroute on macOS sends UDP datagrams to unlikely high ports starting at 33434 and treats an ICMP Port Unreachable (type 3, code 3) as the arrival signal, while Windows tracert sends ICMP Echo Requests and stops on an Echo Reply. That difference is not cosmetic. Firewalls treat UDP probes and ICMP Echo very differently, so the same destination legitimately produces different asterisk hops from a Mac and from a Windows machine: worth checking both before you blame a router. Which brings us to the question everyone gets wrong, including an earlier version of this page: can a sandboxed app do this at all? The reasoning that says no goes like this. /usr/sbin/traceroute on macOS is installed setuid root while /sbin/ping is not, so traceroute must need privileges ping does not; the App Sandbox grants no such privileges; therefore no traceroute in an App Store app. Every step sounds reasonable and the conclusion is still wrong, because the premise conflates the BSD traceroute's chosen probe type with traceroute as a technique. That binary probes with UDP datagrams and needs a raw socket to read the ICMP errors those provoke, hence setuid. Probe with ICMP Echo instead, and the replies arrive on the same datagram ICMP socket that ping already uses without privileges. setsockopt(IP_TTL) is not a privileged call. So SSHive does not drive the system binary at all. It opens socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP), sets the TTL, sends three Echo Requests per hop, and reads whatever comes back: a Time Exceeded naming a router, an Echo Reply meaning the destination answered, or nothing within two seconds, which prints as an asterisk. That was measured under sandbox-exec with the app's real entitlements before any of it shipped, and it revealed one trap worth repeating: with com.apple.security.network.client alone, the probe goes out and the reply is refused with EPERM, a silent failure that looks exactly like a filtering network. com.apple.security.network.server is required as well. SSHive declares both, which is why the sandboxed App Store build traces at all instead of printing a column of asterisks. iOS reaches the same place by the same route. Network.framework exposes TCP, UDP, QUIC and TLS and no ICMP at all, but it is not the only API available: the BSD socket layer underneath accepts the identical datagram ICMP socket, and Apple's own SimplePing sample has demonstrated it for years. The iPhone and iPad builds run the same thirty-hop, three-probe loop as the Mac. Know the limits before you lean on it. The hop ceiling is fixed at 30, there are no protocol, port or probe-count switches, and there is no ASN or geolocation enrichment. Because the probes are ICMP Echo rather than UDP, a firewall that permits one and drops the other can produce a different asterisk pattern than /usr/sbin/traceroute would; neither result is wrong, and comparing the two is occasionally how you find the firewall.

Related tools