Your redirects work in the browser. That's exactly why nobody notices the ranking signal leaking out of them.
A redirect that "works" only proves one thing: the browser eventually reached the right page. It says nothing about whether Google passed authority to that page, how many round trips the user paid for along the way, or whether a CDN rule is quietly fighting your server config. Redirects are infrastructure that almost everyone treats as a binary (it loads or it doesn't), and that is exactly why ranking signal and page speed leak out of them without anyone filing a bug.
The leaks are specific and fixable. A 302 used for a permanent move tells Google to keep the old URL indexed. A three-hop chain adds three full network round trips before the first byte of real content. A loop throws ERR_TOO_MANY_REDIRECTS and takes the page out of the index entirely. None of these are visible from a green checkmark in DevTools, but all of them are visible the moment you read the status codes hop by hop. This post is about reading them.
What's in this post
- 301 vs 302: the one-character difference that caps your rankings
- Why every extra hop costs you a round trip
- Redirect loops and the rules that cause them
- The fix: one canonical host, one hop
- Tracing a chain in one command
301 vs 302: the one-character difference that caps your rankings
The HTTP status code you return on a redirect is not cosmetic. It is an instruction to the search engine about what to do with the old URL and where the ranking signal should go.
A 301 (Moved Permanently) says the resource has moved for good. Google treats it as a strong signal to index the new URL and pass the accumulated authority to it. A 302 (Found) and a 307 (Temporary Redirect) say the move is temporary: keep the original URL indexed, because it is coming back. The MDN reference on redirection status codes lays out the full set, and Google Search Central's guidance on redirects and Search is explicit that a 301 is the right tool for a permanent move.
Here is the failure mode that costs people rankings and never throws an error: you migrate a page permanently, but your framework or proxy issues a 302 by default. The browser follows it, the user sees the new page, everything looks fine. Google does pass signals through a 302, and if you leave it in place long enough it may eventually reinterpret it as permanent, but you are leaving your rankings to that guesswork, and in the meantime the old URL stays indexed and the new page is treated as a temporary stand-in that does not inherit the old page's authority. You have permanently moved your content and told the search engine it is temporary. Change one digit to a 301 and you stop gambling.
STATUS | NAME | TELLS GOOGLE | USE FOR
---------------------------------------------------------------------------------------
301 | Moved Permanently | index new URL, pass authority | permanent moves
308 | Permanent Redirect | same as 301, keeps request method | permanent moves (POST)
302 | Found | keep old URL indexed, may not pass | genuine temporary moves
307 | Temporary Redirect | same as 302, keeps request method | genuine temporary moves
The rule is boring and absolute: if the move is permanent, return a 301 (or 308 if you need to preserve the request method). Reserve 302 and 307 for genuinely temporary situations, like a maintenance page or a short A/B redirect you will remove next week.
Why every extra hop costs you a round trip
A redirect is not free. Each hop is a full request and response: a connection opens, TLS negotiates, the server answers with a 3xx and a Location header, and only then does the browser start the next request. That is a network round trip the user pays for before any real content arrives.
So a chain like A -> B -> C is not "one redirect." It is two extra round trips stacked in front of the page, and on a high-latency mobile connection each one can add hundreds of milliseconds. That time lands directly on Time to First Byte, the floor under Largest Contentful Paint, which is why Core Web Vitals scores quietly refuse to improve on pages buried behind redirect chains. The front end can be perfect and it will not matter, because you spent the budget before the HTML shipped.
There is a second cost. Google does not follow chains forever, and long chains dilute signal at every step. Per Google Search Central, Googlebot follows up to 10 redirect hops in a chain before giving up on that crawl attempt. The takeaway is the same either way: keep chains short, and ideally collapse them to a single hop. A link pointing at A should reach C in one redirect, not by walking through B first.
SLOW A 301-> B 301-> C (2 round trips before content, signal diluted per hop)
FAST A 301-> C (1 round trip, signal passed directly)
Redirect loops and the rules that cause them
A redirect loop is the failure that takes a page out of the index completely. URLs point back at each other (A -> B -> A) or a URL redirects to itself, so the chain never resolves. The browser eventually gives up and shows ERR_TOO_MANY_REDIRECTS, and Googlebot, hitting the same wall, cannot index the page at all.
Loops are almost never written on purpose. They emerge when two layers of your stack disagree about what the canonical URL is, and each "fixes" the other's output:
- A trailing-slash rule in your CMS adds
/, while a server rewrite strips it, so each bounces to the other forever. - A www and HTTPS redirect at the CDN sends
http://example.comtohttps://www.example.com, while an origin rule sendswwwback to the apex, and they ping-pong. - A lowercase rule and a path-rewrite rule each rewrite the other's result.
The common thread is that the redirect logic lives in more than one place (CMS, CDN, and server config) and no single layer owns the final answer. The browser is not buggy; it is faithfully executing two rules that contradict each other.
The fix: one canonical host, one hop
The entire class of redirect problems collapses if you enforce one rule: pick a single canonical host and send every other variant straight to the final URL with a 301.
- Choose one host. Either
www.example.comorexample.com, and always HTTPS. There is no SEO advantage to either www or non-www. Pick one and commit. This is the same canonicalization discipline you apply with a canonical tag checker, enforced at the redirect layer instead of in the<head>. - Redirect every other variant to it, in one hop. The four common variants (
http://example.com,http://www.example.com,https://example.com,https://www.example.com) should all 301 directly to the one canonical URL. Do not chainhttp -> https -> www. Map each variant to the final destination directly. - Own the logic in one place. Decide whether the CDN or the origin server enforces canonicalization, and disable the redundant rules in the other layer. One owner means no two rules can contradict each other, which is what kills loops.
- Update internal links to point at the destination. Every redirect you can avoid is a round trip you do not pay for. If your nav, sitemap, and internal links already point at the canonical HTTPS URL, the redirect is a safety net for external links, not a tax on your own traffic.
The target state is one permanent redirect, never a chain, with a single layer in charge. Everything else (the speed, the passed authority, the absence of loops) follows from that.
Tracing a chain in one command
You cannot fix what you cannot see, and the browser hides the chain by only showing you the final page. To read it hop by hop, ask for headers and tell the tool to follow redirects:
curl -IL https://example.com
-I requests headers only (a HEAD request), and -L follows the Location header through every hop. The output prints one block per hop, so you read the status line and Location of each:
HTTP/2 301
location: https://www.example.com/
HTTP/2 301
location: https://www.example.com/home
HTTP/2 200
That is a two-hop chain (example.com -> www.example.com/ -> www.example.com/home) that should be a single 301 to /home. If you saw 302 on a permanent move, that is the capped-authority bug. If curl printed curl: (47) Maximum (50) redirects followed, you have a loop. Reading those three lines tells you the status code, the type, and the exact Location at every step, which is everything you need to diagnose the problem.
Doing that by hand for every URL variant (four host combinations, with and without trailing slashes) is tedious, and it is easy to miss the one variant that loops. The LintPage redirect checker follows your URL hop by hop and reports the whole path in one shot: every hop with its status code, 301 versus 302/307, chains longer than one hop, loops that never resolve, the HTTP to HTTPS upgrade, and the final destination and status. It is the same status-code reading you would do with curl -IL, laid out so the leak is obvious.
Redirect problems rarely travel alone: the same migration that left a 302 in place tends to leave stale canonical tags and broken internal links too. It is worth running the full audit once the chain is clean.
The 30-second version
A redirect that loads in the browser can still be leaking rankings and speed. The status code is the instruction: a 301 passes authority to the new URL, while a 302 or 307 tells Google to keep the old URL indexed, so a 302 on a permanent move leaves the wrong URL indexed and risks capping the new page's ability to rank while Google decides whether to reinterpret it. Every extra hop is a full network round trip that inflates TTFB and hurts Core Web Vitals, and Google stops following long chains, so collapse A -> B -> C into A -> C. Loops throw ERR_TOO_MANY_REDIRECTS and de-index the page; they come from CMS, CDN, and server rules contradicting each other. The fix is one rule: pick one canonical host (www or non-www, always HTTPS), 301 every other variant straight to the final URL, and own the logic in one layer. Trace it with curl -IL https://example.com and read the status code and Location at every hop.