A link lands somewhere it should not, and you need to know what happened between the click and the final page. The standard first move is curl, and it is the right one: the 60 second gclid test on this site is built on curl -sIL, and for server redirects it tells the truth. Then the chain looks clean in the terminal while the browser still ends up somewhere else, and the tool has quietly run out.

The reason is that only some redirects live in HTTP responses. The rest happen inside the page, or inside the browser itself, and no amount of -L will surface them. This article is about seeing a chain, not building one; every way to create a redirect on Cloudflare is its own comparison.

Three redirects curl cannot show you

A JavaScript redirect is a 200. The server answers with a normal page, the page runs location.replace() or sets location.href, and the browser navigates. curl prints HTTP/2 200, reports no redirect at all, and exits. Every interstitial, every tracking hop built on a script, every “checking your browser” page falls in this class.

A meta refresh is also a 200. <meta http-equiv="refresh" content="0;url=..."> sits in the HTML body, and curl does not parse HTML. Same clean status line, same silent navigation in the browser.

An HSTS upgrade never leaves the browser. After one visit to a site that sends Strict-Transport-Security, the browser rewrites http:// to https:// before any request is made. DevTools shows it as 307 Internal Redirect, a response the server never sent. curl keeps no HSTS state by default, so it hits the http:// URL fresh every time and shows you the server’s 301, a hop your returning visitors stopped taking long ago.

301, server hop
curl sees it

HSTS 307, internal
repeat visits, browser only

302, server hop
curl sees it

200 + location.href
browser only, curl stops here

http://go.example/deal

https://go.example/deal

https://shop.example/landing

https://shop.example/en/deal

One chain, two stories: every hop of it, and where curl stops reading

On top of the mechanics there is the session. curl carries no cookies, so a chain that branches on login state, a consent cookie, or an A/B assignment sends curl down a different path than the person who reported the problem. The chain you tested is not the chain they followed, even when both are real.

DevTools shows it, if you hold it right

The browser obviously knows the full chain, and the Network panel will show it, with ceremony. Preserve log has to be on, otherwise the panel clears itself on every navigation and the hop you care about erases its own evidence. The Doc filter cuts the noise from the hundred subrequests a modern page makes. Server hops then appear as separate rows with their 301 and 302 statuses.

The client side hops are there too, but unlabeled. A JavaScript redirect is just another document request; nothing in the row says “this was a redirect”, and connecting it to the page that triggered it means reading the Initiator column. A meta refresh looks the same. Do this once and it is five minutes of archaeology. Do it for every report and you start wanting the browser to just keep the record.

A recorder instead of a stakeout

That is what Redirect Inspector does. It is our own open source extension (Apache 2.0, code on GitHub), and version 2.3 shipped as its largest update yet, which is the occasion for this article. The extension listens to the browser’s own request pipeline and records every chain as you browse: server hops with their status codes, client side navigations (a script or a meta refresh) marked with a JS badge, and the browser’s internal upgrades marked HSTS. Chains are grouped by browsing session, tracking pixels and ad beacons are filtered out by default, and each card carries the total chain time with per hop timing in the analysis drawer.

What 2.3 added, briefly:

  • Check a URL without visiting it. Paste a URL into the dock at the bottom of the panel; it opens in an invisible background tab, the chain is captured through the normal pipeline, and the tab closes itself. The suspicious link from the report gets traced without ever taking over your screen.
  • Export that fits a bug report. Copy a clean summary, download the raw chain as JSON, or copy a ready curl command that reproduces the server side of the chain, which closes the loop back to the terminal where the investigation started.
  • A side panel instead of a popup on Chrome and Edge, so the chain list stays open while you browse. Firefox keeps the popup.
  • Local analysis. Nine checks per chain: loops, hops that bounce back and forth, chain length, mixed redirect types, auth bounces, consent hops, tracking noise, CDN detection, final outcome.
  • Search across all captured URLs, an undoable Clear, keyboard shortcuts, and full UI translations in seven languages.

The part that matters for a tool watching your traffic: everything runs locally. No accounts, no analytics, no telemetry, and by default no network requests at all; captured chains live in browser storage and never leave the machine. It is on the Chrome Web Store, Firefox Add-ons, and Edge Add-ons.

Which tool sees what

You need curl -sIL DevTools Network Redirect Inspector
Server hops (301, 302, 307, 308) yes with Preserve log on yes, recorded as you browse
HSTS upgrade no, sees the server 301 every time shown as 307 Internal Redirect labeled HSTS
JS and meta refresh no, both are a 200 an unlabeled document request captured, marked as a client redirect
The chain your session gets (cookies, login) no yes yes
Timing one total with -w per request, spread across rows total per chain, delta per hop
A record you can search and export later no cleared when the panel closes sessions, search, JSON and curl export

Online redirect checkers are missing from the table on purpose: they request the URL from their own datacenter, so a chain that branches on country, language, or cookies shows you the datacenter’s version, which is the same blind spot curl has plus somebody else’s IP.

Where the extension stops

The extension records what your browser was sent. A chain that branches by geography still shows you the branch for your country and nobody else’s, and what Googlebot sees on the same URL is a different question entirely. The URL check is a real navigation in an inactive tab, so your cookies apply and the visit lands in your history; it is a convenience, not an isolation chamber. And it can only look at chains one browser at a time, on the machine where it is installed.

For debugging the link in front of you, that is the whole job, and the extension is free. The point where it stops is the point where the question changes from “what happened to this click” to “which of my domains are redirecting wrong right now”. Answering that means sending the same probe to every domain on a schedule and comparing against yesterday, which no browser tool can do. The audit script is the manual version of that answer, and 301.st is the version that runs continuously, across the portfolio, with an alert when a chain changes. For the tab you have open, install the extension and read the chain.