Skip to content
Live diagnostic

Redirect Loop Checker

Test all four versions of your URL in one run — http and https, www and non-www — and see which pair of rules is sending requests back and forth. Free, no signup.

>

When a page dies with ERR_TOO_MANY_REDIRECTS, the browser tells you almost nothing: not which URL started the cycle, not which rule closed it, not whether the problem is on the server at all. This tool requests all four versions of the address a visitor might arrive on — HTTP and HTTPS, with and without www — because that disagreement is where loops live. The www/non-www conflict is the most common shape by a wide margin: one layer redirects the bare domain to www, another redirects www back, and each rule looks perfectly reasonable on its own.

Each variant gets its own verdict, and they often disagree. A loop on http://www.example.com can be invisible on https://example.com, which is why testing the single address in your browser bar sends people editing configs at random. Four cookie-less traces tell you which entry points are broken, which two rules to open, and — when all four resolve — that the loop is in your browser’s stored state rather than on the server.

Testing every version of your URL before you debug

Most loop reports start with one address: whatever was in the browser bar when the error appeared. Testing that single address proves almost nothing. A host or protocol redirect only fires for the form it was written to catch, so example.com and www.example.com can behave completely differently, and a domain that cycles forever over HTTP may answer in one clean hop over HTTPS. A lot of .htaccess has been rewritten at 2am because the variant that got tested was the variant that happened to work.

Every domain has four entry points, and the checker above requests all of them in sequence:

https://example.com/checkout
https://www.example.com/checkout
http://example.com/checkout
http://www.example.com/checkout

Your path and query ride along on all four, so /checkout?step=2 is traced as /checkout?step=2 on each one. The traces run separately and without cookies, which means a variant that loops does so for every first-time visitor who enters through it, not just for you.

The useful part is that a loop rarely exists on all four. Which subset breaks is itself the diagnosis, because it tells you what a request has to look like before the bad rule fires:

Loops onWhat that narrows it to
www variants onlyA host conflict, with the bare domain as the intended canonical. One layer routes www to example.com, another routes it back. Requests that start bare never meet the first rule, so they load.
Bare-domain variants onlyThe same host conflict with the canonical reversed. A rule that adds www is fighting one that strips it, and only requests arriving without www trigger both.
http variants onlyProtocol enforcement running twice in opposite directions. Almost always a CDN fetching your origin over plain HTTP while the origin insists on HTTPS.
A single variantTwo changes have to stack before the loop appears — the host and the protocol. The two rules that produce those two changes are your pair.
All fourThe rule fires no matter how the request arrives, so the entry point is not the trigger. Look inside the application: a CMS canonical redirect, a rewrite rule that matches its own output, or a login or consent guard.

Done by hand, this is four curl -I -L runs and four sets of Location headers to line up side by side. That comparison is the step nearly every fix-it guide leaves out, and it is the one that names the guilty pair.

Which rule is fighting which

A www/non-www loop needs exactly two rules, and both of them are usually correct. The first lives at the edge: a Cloudflare redirect rule, a Netlify or Vercel domain setting, a load balancer rule that names www.example.com as the canonical host and 301s the bare domain to it. The second lives at the origin: a RewriteRule in .htaccess, an nginx server block with a return 301, or the siteurl/home pair in WordPress that names example.com and sends www back. Both rules enforce a canonical host. They simply disagree about which host that is.

Read either one alone and it passes review. The CDN rule is textbook: one hostname, one permanent redirect, no ambiguity. The .htaccess block is the snippet every hosting tutorial publishes. Nothing is misspelled and no syntax is wrong, so a config review finds nothing. The failure exists only in the combination, and the two halves usually have different owners and different ages — the edge rule went in when somebody moved DNS to a CDN, the origin rule came with the theme or survived a migration years earlier. That is why “check your redirects” advice so rarely lands. You open one file, see a rule that is obviously right, and close it.

The four-variant trace identifies the pair because it shows both halves in one list, with a timing on each hop:

1  https://example.com/pricing        301 → https://www.example.com/pricing      3ms    ← edge rule: add www
2  https://www.example.com/pricing    301 → https://example.com/pricing        180ms    ← origin rule: strip www
3  https://example.com/pricing        301 → https://www.example.com/pricing      3ms    ← returns to hop 1

Hop 1 came back in 3ms, far too fast to have reached your server, so an edge rule answered it. Hop 2 took 180ms, which is roughly what the site costs on a normal request, so that one is your origin. You now know both the direction each rule pushes and which layer holds it, which is enough to open the right two configs on the first try instead of the fifth.

The fix is a decision, not a patch. Pick one canonical host and write it down. Then make every rule emit that host: the CDN or platform redirect, the server config, the CMS site URL, the sitemap, your internal links and your canonical tags. Finally, delete the second rule rather than reversing it. Reversing turns two contradicting rules into two agreeing rules that both still fire, and you trade a loop for an extra hop on every request plus a fresh loop the day someone edits one of them back. One canonical host, one redirect rule, one hop.

Re-run all four variants when you are done. Three of them should redirect once into the canonical host and stop; the canonical itself should answer 200 with no redirect at all. Anything else means a third rule is still in play. The www ↔ non-www pattern card below shows the trace this produces when it is still broken.

How to read your result

Each variant gets its own verdict. Loop detected at hop N — returns to hop M means the trace fetched a URL at hop N whose redirect points back at a URL it already visited at hop M. The hops between M and N are the cycle, and they're outlined in red in the hop list: those are the URLs bouncing between each other, and the rules answering them are the ones to fix. Every hop shows its status code and response time, so you can often tell which layer answered — a 1–5ms hop is usually a CDN edge rule, a slower one is your origin.

Suspected loop (trace exhausted its hop budget) means the trace followed its maximum number of redirects without ever seeing the exact same URL twice. That's typical of loops that mutate the URL each pass — appending query parameters, alternating session tokens — so no single hop literally repeats, but the sequence clearly never lands. Treat it as a loop: a real visitor's browser gives up on it just the same.

And when all four variants resolve cleanly, the result says so honestly instead of inventing a problem: the server, approached without cookies, is fine. Your loop is client-side — see the cookie-gated pattern below for why that happens and the two-minute fix.

What is a redirect loop?

A redirect loop is a redirect sequence that revisits a URL it has already been through. URL A answers "go to B," B answers "go to A" — or any longer circle — so the request never reaches a page that returns content. The mechanism is always the same: two pieces of configuration hold contradictory opinions about the canonical form of a URL, and each one dutifully "corrects" the other's output. Neither rule is broken in isolation; the loop exists only in their combination, which is why it so often appears the moment a second layer (a CDN, a plugin, a proxy) is added in front of a working site.

Browsers keep a redirect counter and quit when it runs out. Each one words the failure differently, which matters when you're matching a user's screenshot to a diagnosis:

BrowserError wording
ChromeThis page isn't working — example.com redirected you too many times. (ERR_TOO_MANY_REDIRECTS)
FirefoxThe page isn't redirecting properly — Firefox has detected that the server is redirecting the request in a way that will never complete.
SafariSafari can't open the page — too many redirects occurred trying to open this page.
EdgeThis page isn't working right now — example.com redirected you too many times. (ERR_TOO_MANY_REDIRECTS)

Different words, one condition: the redirect counter hit its ceiling before any hop returned content. Whatever the browser calls it, the trace above shows the actual hops behind the error.

The loop patterns this checker detects

Nearly every loop in the wild is one of five shapes. When a trace confirms a loop, the checker names the shape it found and links to the matching fix below — each card shows a real trace of the pattern so you can recognize yours at a glance.

HTTP ↔ HTTPS ping-pong (double HTTPS enforcement)

1  http://shop.example/cart    301 → https://shop.example/cart
2  https://shop.example/cart   301 → http://shop.example/cart    ← returns to hop 1

Two layers both enforce the protocol in opposite directions. The classic setup: Cloudflare's Flexible SSL fetches the origin over HTTP, the origin's .htaccess forces HTTPS, and the request bounces between them forever. Also seen with load balancers that terminate TLS but don't pass X-Forwarded-Proto, so the app thinks every request is insecure.

Fix: Let exactly one layer own the HTTP→HTTPS redirect. On Cloudflare, switch SSL/TLS to Full (strict) with a certificate on the origin. Behind a load balancer, make the app trust X-Forwarded-Proto before deciding to redirect.

www ↔ non-www cycle

1  https://example.com/about      301 → https://www.example.com/about
2  https://www.example.com/about  301 → https://example.com/about    ← returns to hop 1

One rule adds the www prefix, another strips it. It happens when the CDN holds one canonical-host rule and the server config holds the opposite — or when a migration changed the canonical host but an old rule survived in .htaccess, nginx, or an SEO plugin.

Fix: Pick one canonical host, then hunt down every host redirect across CDN rules, server config, and CMS settings, and delete all but one. The trace above shows you which layer answers each hop by its latency and headers.

Trailing-slash cycle

1  https://example.com/docs   301 → https://example.com/docs/
2  https://example.com/docs/  301 → https://example.com/docs    ← returns to hop 1

One layer appends a trailing slash while another removes it, so the path toggles between /docs and /docs/ forever. Typical after fronting a slash-adding CMS (WordPress, Django) with a slash-stripping proxy rule, or enabling a 'remove trailing slashes' toggle in a framework that a CDN rule contradicts.

Fix: Decide the slash policy once, in one place — usually the CMS or framework — and remove the competing rule from the web server or CDN. Then update internal links to the canonical form so the remaining redirect rarely fires at all.

Self-redirect

1  https://example.com/login   302 → https://example.com/login    ← returns to hop 1

The Location header resolves to the exact URL that was requested. Usually a rewrite rule that fires again on the URL it just produced, a language or geo redirect whose condition never becomes false, or a login redirect pointing at itself when the session check misfires.

Fix: Find the rule whose destination matches its own trigger and add a stop condition — in Apache, guard the RewriteRule with a RewriteCond that excludes the destination; in app code, only redirect when the current URL actually differs from the target.

How to fix ERR_TOO_MANY_REDIRECTS, in order

Work down this ladder and stop at the first rung that clears the loop. It's ordered from the cheapest check to the most invasive, and from the most common cause to the rarest — most loops die at step 3 or 4.

  1. 01

    Clear cookies for the affected site only. Browsers cache 301s and servers key redirects off session cookies, so stale state alone can loop a perfectly healthy site. Click the icon left of the address bar → Cookies and site data → remove — no need to wipe your whole browser.

  2. 02

    Run the checker above to prove server vs browser. The trace is cookie-less: if any variant loops here, the server is misconfigured and the steps below apply. If all variants resolve cleanly, the loop was client-side and step 1 already fixed it.

  3. 03

    Check for double HTTPS enforcement. The most common server-side cause is two layers both redirecting the protocol — the CDN upgrades visitors to HTTPS while the origin, seeing plain HTTP from the CDN, redirects back. Exactly one layer should own the HTTP→HTTPS redirect.

  4. 04

    Check your CDN or proxy's SSL mode. On Cloudflare, Flexible mode talks plain HTTP to your origin; if the origin forces HTTPS you get an endless ping-pong. Install a certificate on the origin and switch to Full (strict).

  5. 05

    Check the CMS URL settings. In WordPress, a siteurl/home pair that disagrees with the server (http vs https, www vs bare) makes the CMS redirect every request to an address another layer redirects right back.

  6. 06

    Disable redirect plugins. SEO and redirection plugins each add their own rules, and two plugins enforcing opposite canonical forms is a loop. Deactivate them one at a time — via SFTP (rename the plugin's folder) if the admin area is unreachable.

  7. 07

    Reset rewrite rules. Restore a default .htaccess (or your framework's stock rewrite block), confirm the loop is gone, then re-add custom rules one by one, re-running the trace after each. The rule that brings the loop back is your culprit.

After every change, re-run the trace above rather than your browser — the browser may serve you a cached redirect long after the server is fixed, and the cookie-less trace answers with the server's current behavior only.

The WordPress + Cloudflare Flexible SSL loop

This one combination causes so many loops it deserves its own walkthrough. Cloudflare's Flexible SSL mode gives visitors HTTPS at the edge but fetches your origin over plain HTTP. WordPress, whose Site Address is set to https://, sees an HTTP request arrive and issues a 301 to the HTTPS URL. Cloudflare receives that redirect, the visitor's browser follows it — and Cloudflare fetches the origin over plain HTTP again. Edge and origin each believe they're enforcing the right thing; together they ping-pong forever. Any HTTPS enforcement at the origin triggers it: WordPress's own canonical redirect, an .htaccess rule, or a security plugin's "force SSL" option.

The real fix is to stop speaking HTTP between Cloudflare and your origin. Install a valid certificate on the origin server (Cloudflare's free Origin CA certificate works, or Let's Encrypt), then set SSL/TLS mode to Full (strict) in the Cloudflare dashboard. Now the edge fetches your origin over HTTPS, WordPress sees a secure request, no redirect fires, and the loop is gone. Avoid plain "Full" long-term — it skips certificate validation — and never "fix" the loop by removing HTTPS enforcement at the origin while staying on Flexible, which leaves origin traffic unencrypted.

Locked out of wp-admin by the loop? Work over SFTP. Add define('WP_HOME','https://example.com'); and define('WP_SITEURL','https://example.com'); to wp-config.php to pin the canonical URL above anything the database says. If a plugin is forcing the redirect, rename wp-content/plugins to deactivate everything at once, log in, rename it back, and re-enable plugins one at a time until the loop returns. If the rules live in .htaccess, restore the stock WordPress block and re-add customizations one by one.

Two variants of the same trap: Cloudflare's Always Use HTTPS toggle adds an edge-side HTTP→HTTPS redirect, which is fine alone but joins the loop if the origin also downgrades or upgrades the protocol. And HSTS makes loops stickier: once sent, browsers refuse HTTP for the whole max-age, so even after you fix the server, visitors' browsers keep replaying the upgrade — another reason the cookie-less trace above is the reliable way to confirm a fix landed.

Redirect loops and SEO

An unreachable page is an unindexable page. Googlebot follows a redirect sequence for about 10 hops before it abandons the URL and records a redirect error in Search Console — and a loop spends that entire budget cycling the same two or three addresses. The looping URL drops out of the index once recrawls keep failing, and every internal and external link pointing at it becomes a dead end: the equity those links carry has nowhere to land, because the destination never resolves to content.

The timing makes it worse. Loops don't develop gradually — they switch on in a single deploy, SSL change, or plugin update, usually on a Friday. Rankings don't fall the moment the loop appears; they fall days later, when enough failed recrawls convince Google the page is gone, and recovering a dropped URL takes far longer than the outage that caused it. That gap between "loop appears" and "rankings react" is exactly the window monitoring exists for: watch the URL, get alerted on the first failed trace, and fix the rule before the crawler draws conclusions.

Redirect loop vs chain: how to tell which you have

The two problems look similar in a trace but differ in the only way that matters: a chain ends at a 200, a loop never resolves. A chain — A to B to C to a real page — is a tax: every visit pays extra round trips, crawlers spend budget on plumbing, and a little link equity leaks at each transfer. Slow, wasteful, but the page works. A loop is an outage: the sequence folds back on itself, no request ever reaches content, and for anyone entering through the looping variant the page is simply down. Fix chains when you get to them; fix loops now.

If your trace shows hops that keep moving forward and finish on a 200, your problem is a chain, and the right tool is the redirect chain checker, which measures per-hop latency and shows you how to flatten the path to a single hop. If any variant above came back red, stay on this page — the fix ladder and pattern cards are the way out.

Frequently asked questions

Why does my site redirect between www and non-www?
Because two rules disagree about which host is canonical, and each one is doing exactly what it was written to do. The usual pair: a CDN or platform setting redirects the bare domain to www, while an origin rule sends www back to the bare domain — an .htaccess RewriteRule, an nginx server block, or the siteurl/home pair in WordPress. Neither layer knows the other exists, so requests bounce between them until the browser gives up with ERR_TOO_MANY_REDIRECTS. Trace all four variants above and read the hop timings: the hop answered in a few milliseconds is the edge rule, the slower one is your server.
How do I test all versions of my URL for a redirect loop?
Enter the domain above. The checker requests all four entry points — http and https, with and without www — traces each one separately, and preserves your path and query on every variant. You get four independent verdicts instead of one. By hand the same job is four curl -I -L runs and four sets of Location headers to line up side by side, which is why most people test the address in their browser bar and stop there.
How do I find which redirect rule is causing the loop?
Work from the hop list, not from your config files. Every hop shows the URL requested, the status, the Location it points at, and how long the answer took. The difference between a hop's URL and its Location tells you what the rule does: adds www, strips www, upgrades the protocol, toggles a trailing slash. The response time tells you who did it. Single-digit milliseconds means a CDN edge rule answered without ever reaching your origin; anything near your site's normal response time is the server or the application. Two hops that undo each other are your pair, and you now know which two configs to open.
ERR_TOO_MANY_REDIRECTS on www but not non-www — why?
The looping rule only fires for requests that arrive carrying www. Something redirects www.example.com to example.com, something else sends it straight back, and a visitor who types the bare domain never triggers the first rule — so the site loads normally for them and breaks for anyone who follows a www link. That asymmetry is useful: it means the conflict is over the host, not the protocol, which rules out the SSL-mode causes completely. Compare the host redirect at your CDN with the host redirect at your origin. One of the two is redundant.
Should I use www or non-www?
Either is fine. Google treats www.example.com and example.com as separate hosts and follows whichever one you nominate as canonical, with no ranking advantage on either side. www is slightly easier to operate, since a CNAME can point it at a CDN and cookies set there stay off your other subdomains; the bare domain is shorter and reads better in print. Pick one, then make every rule, internal link and canonical tag emit that one. Consistency is the whole point. The loop you are debugging came from two rules choosing differently, not from choosing wrong.
What causes ERR_TOO_MANY_REDIRECTS?
Two rules that disagree about where a URL should live. One layer redirects to HTTPS while another sends visitors back to HTTP, one adds www while another strips it, or a rewrite rule fires again on the URL it just produced. The most common single cause is double HTTPS enforcement — a CDN like Cloudflare in Flexible SSL mode plus an origin server that forces HTTPS. Stale cookies can also trigger it: the server loops only for requests carrying your browser's stored session state.
My browser shows a redirect loop but this tool finds none — why?
This trace is cookie-less, so it sees the site the way a first-time visitor does. If every variant resolves cleanly here but your browser still loops, the server is reacting to state your browser sends — usually a session cookie, a cached 301, or a consent/login flow that keeps bouncing you. Clear cookies for that site only (not your whole browser) and retry in an incognito window. If incognito loads the page, the loop lives in your normal profile's stored state, not on the server.
How many redirects before a browser gives up?
Chrome and Firefox stop following after roughly 19–20 hops and show their loop error. curl follows up to 50 with the --location flag before aborting. Googlebot is far less patient: it abandons a redirect sequence after about 10 hops and reports the URL as a redirect error. A genuine loop burns through every one of those budgets instantly, because the same two or three URLs repeat until the counter runs out.
Why does Cloudflare cause a redirect loop on WordPress?
Cloudflare's Flexible SSL mode serves visitors HTTPS but fetches your origin over plain HTTP. If WordPress (or your .htaccess) then redirects HTTP requests to HTTPS, every request ping-pongs: Cloudflare asks for HTTP, the origin answers 'go to HTTPS', Cloudflare asks for HTTP again. The fix is in the WordPress + Cloudflare Flexible SSL section above: install a certificate on the origin and switch Cloudflare's SSL/TLS mode to Full (strict) so both layers speak HTTPS.
How do I fix a WordPress redirect loop when I'm locked out of wp-admin?
You can fix it without the dashboard. Over SFTP, add define('WP_HOME','https://example.com'); and define('WP_SITEURL','https://example.com'); to wp-config.php to pin the canonical URL. If a plugin is looping, rename wp-content/plugins to plugins-off to deactivate everything at once, log in, then rename it back and re-enable plugins one at a time. If rewrite rules are the culprit, replace .htaccess with the WordPress default block. Each change takes effect immediately — re-run the trace between steps.
Is a redirect loop bad for SEO?
Worse than a long redirect sequence. A slow path still delivers the page eventually; a loop never does, so the URL is unreachable and therefore unindexable. Googlebot gives up after about 10 hops, marks the URL as a redirect error, and every link pointing at it dead-ends its equity. Because loops usually appear right after a deploy or an SSL change — exactly when you're not looking — watching the URL and getting alerted the moment a loop appears is what keeps a config slip from becoming a deindexed page.
What's the difference between a redirect loop and a chain?
A chain moves forward: A points to B, B points to C, and C finally answers 200 — slow, but the visitor gets a page. A loop points backward: some hop's destination is a URL that was already visited, so the sequence cycles until the browser quits with an error. A chain is a performance and crawl-budget tax you should flatten; a loop is a full outage for that URL and needs fixing the moment it appears.
Will a redirect loop fix itself?
A server-side loop won't — the two rules that contradict each other keep contradicting each other until someone changes the config. The only loops that seem to fix themselves are cookie-gated ones: the loop clears when the offending cookie expires or the visitor clears site data, which is also why the same URL can work for some visitors while looping for others. If this checker confirms a loop on any variant, treat it as down and fix the rule — waiting changes nothing.

Related tools