Website problems
Redirect loop
A redirect loop is a URL that redirects, directly or through several hops, back to a URL already visited in the same chain. Nothing ever returns a final response, so browsers stop after a fixed number of attempts and show an error — `ERR_TOO_MANY_REDIRECTS` in Chrome. Unlike a long redirect chain, which is slow, a loop makes the page unreachable. It is an availability failure and it outranks every performance consideration on the same URL.
The four pairs that cause it
Trailing slash against no trailing slash. One rule adds it, another removes it, and every request alternates. The most common loop on the web.
Protocol against host. A rule forcing HTTPS and a rule forcing the `www` host, written so that each undoes part of the other's work.
A load balancer terminating TLS and forwarding plain HTTP to the origin. The application sees an insecure request, redirects it to HTTPS, the balancer terminates again and forwards HTTP again. This one is invisible from the application's own configuration.
Locale detection. A rule redirecting to a language prefix and a rule stripping the prefix when it matches the default, each firing on the other's output.
What they share: two rules, each correct alone, written by people who did not compare them.
Why it is hard to diagnose from inside
A redirect can be issued from four layers — the registrar's domain forwarding, the CDN or edge proxy, the web server, and the application — and they all produce the same response.
Someone editing the application's routing sees no loop in the code, because half the loop is a CDN page rule nobody opened.
Caching makes it worse: an edge rule changed may still be served from cache, so a correct fix appears to do nothing and is reverted.
And a loop is often conditional. It fires for one host, or one path shape, or only for requests arriving without a cookie — so it does not reproduce on the developer's machine.
The reports that reach you are also misleading. A visitor describes a page that will not load, which sounds like an outage; the site is fine for everyone entering by a different route, so the first response is usually to look for something that is not there.
How to find it
`curl -I -L --max-redirs 10 <url>` follows the chain and prints each hop's status and `Location` header. A repeated URL in that output is the loop, and the pair of hops around it is the disagreement.
Then identify the layer for each hop. Compare the response headers of each: a `server` or `cf-ray` header, or a header the CDN adds, usually tells you whether the origin was reached.
Request the origin directly, bypassing the CDN, if you can. A loop that disappears is an edge rule; one that persists is the server or the application.
Test the whole matrix rather than the URL that broke: both protocols, both hosts, with and without a trailing slash, a deep path, and an old path. Loops are usually conditional on one of those.
Check whether the application is reading a forwarded-protocol header. The TLS-termination loop is fixed there and nowhere else.
How to fix it
Normalise once, in one place. Decide the canonical protocol, host and trailing-slash form, and apply all three in a single rule at the earliest layer that can see the request. Chained partial normalisation is what produces loops.
Order matters: force protocol and host together, then apply path rules to the already-normalised URL.
Where TLS is terminated upstream, make the application trust the forwarded-protocol header instead of the connection it sees.
Change one direction at a time and re-test the matrix after each change. Three rules edited together produce a new loop more often than not.
Keep the intermediate redirects that other URLs rely on. Removing a rule because it participated in a loop converts an unreachable page into a 404.
How VeriFixScan detects it
`availability.redirect_loop` follows the redirects for the URLs the crawler encounters, records the URLs visited, and reports a loop when one repeats — with the full sequence of hops, so the disagreeing pair is visible rather than inferred.
It is reported separately from `transport.redirect_chain`, which measures length. A chain of four hops is slow; a loop is unreachable, and merging the two findings would bury the second in the first.
`transport.canonical_host` and `transport.http_redirect` report the two rules that most often disagree, which is usually where the fix belongs.
Frequently asked questions
- How many redirects before a browser gives up?
- Browsers enforce a fixed limit — commonly around twenty — and then show an error. The exact number varies by browser and is not something to rely on: a loop is unreachable whatever the limit is.
- Why does the loop happen on my server and not locally?
- Because half the loop is usually a layer that only exists in production — a CDN rule, a load balancer terminating TLS, or a domain forward at the registrar. Local environments have none of them.
- Is a redirect loop different from a long redirect chain?
- Yes. A chain resolves eventually and costs latency. A loop never resolves and the page cannot be reached at all, which makes it an availability problem rather than a performance one.
Sources
Related
VeriFixScan crawls a site and applies its checks to every page it reaches, keeping the evidence behind each finding. Scanning one website is free.
Scan a website