Redirect Loops

What redirect loops are, why they take a site down for users and crawlers, common causes (HTTPS/SSL-mode mismatches, www vs non-www conflicts, plugin vs server rules, trailing-slash bugs), and how to diagnose and fix them by cause.

First published: Jul 2, 2026 · Last updated: Jul 18, 2026 · Advanced
demand #7 in Redirects#23 in HTTP Status Codes#145 in Technical SEO#189 on the site
1 evidence signal on this page

A redirect loop is a chain of redirects that circles back on itself — A → B → A, or a longer cycle — so no page ever returns a 200. Browsers surface it as ERR_TOO_MANY_REDIRECTS; in Google Search Console it's one of four documented causes of the 'Redirect error' status. It's a site-outage problem first (real visitors are locked out) and an SEO problem second (Google can't index what it can't reach), and Patrick's framing is that it harms three parties: users, crawlers, and your own server. A well-documented cause is an HTTPS/SSL-mode mismatch between a CDN and the origin (e.g. Cloudflare on 'Flexible' while the origin forces HTTPS); other common causes are www/non-www rules pointing at each other, a plugin rule fighting a server rule, and trailing-slash bugs — no single cause is the universal or most common one across every site. A loop is not a hop-count problem — raising the redirect limit never fixes it. The fix is always specific to the cause: break the cycle, get the final URL to return the correct non-redirect response, and update internal links.

TL;DR — A redirect loop is a cycle of redirects (A → B → A, or longer) that never returns a 200, so it never resolves. It’s categorically different from a long chain — a chain is slow, a loop is broken — which is why raising a hop limit never fixes one. It surfaces as ERR_TOO_MANY_REDIRECTS in the browser and as one of four documented causes of the “Redirect error” status in Search Console. It harms three parties: users (locked out), crawlers (trapped, wasted crawl budget, nothing indexed), and your server (wasted resources, and — depending on traffic, whether the requesting clients back off, and your capacity/rate limits — potentially serious load). A well-documented cause is an HTTPS/SSL-mode mismatch between a CDN/proxy and the origin; others include www/non-www rules pointing at each other, a plugin rule fighting a server rule, and trailing-slash logic bugs — no single cause is universally “the most common” across every site. The fix is always specific to the cause.

A loop is a cycle, not a long chain

The defining property is cyclic routing, not a particular number of hops. Evidence for this claim Primary standard or official documentation supporting the adjacent article claim. Scope: Protocol semantics and Search behavior are kept separate; no indexing, ranking, or migration-timing guarantee is inferred. Confidence: high · Verified: RFC 9110: Redirection Search Console’s label reports the failed redirect path, not the configuration layer that created it. Evidence for this claim Primary standard or official documentation supporting the adjacent article claim. Scope: Protocol semantics and Search behavior are kept separate; no indexing, ranking, or migration-timing guarantee is inferred. Confidence: high · Verified: Google: Page indexing report Treat a repeated URL as a strong trace heuristic, not automatic proof: request state — auth, consent, locale, cookies, or headers — can differ between visits, and a URL that looked like it was cycling can resolve once that state changes. Confirm a true loop by reproducing the cyclic transition under materially equivalent request state (same session, same cookies, same locale) before you call it a loop and go fix a rule.

This is the distinction that makes everything else make sense. Here’s how I define it in my Ahrefs guide to redirects: redirect loops are infinite loops of redirects that occur when a URL redirects to itself, or when a URL in a redirect chain redirects back to a URL earlier in the chain.

A redirect chain (A → B → C → D → final) is a path — it’s just longer than it should be. It eventually reaches a page that returns 200. It’s slow and it’s worth collapsing, but it resolves.

A redirect loop is a circle. A → B → A. It never reaches a 200, no matter how long you follow it. That’s why “just increase the redirect limit” — a reasonable instinct if you’re thinking about chains — is not a valid fix for a loop. A loop doesn’t fail because a browser ran out of patience; it fails because there is no destination to reach. You have to break the cycle, not follow more hops.

How a loop shows up

In the browser. Chrome shows ERR_TOO_MANY_REDIRECTS. Firefox says “The page isn’t redirecting properly.” Safari says “too many redirects occurred.” Edge shows its own “too many redirects” message. Same root cause, different wording.

In Google Search Console. A loop is one of four documented causes of the “Redirect error” status in the Page Indexing report — the others being a redirect chain that was too long, a redirect URL that exceeded the max URL length, and a bad or empty URL in the chain. If you’re seeing “Redirect error” pile up in that report, a loop is one of the four things it could be. That report reflects what Google saw on its last crawl of the URL, not a live, permanently-current verdict — re-check with URL Inspection after you fix the cycle rather than assuming the report updates instantly. (The redirect error status has its own deep dive on this site that covers all four; this article is the one specifically about the loop.)

To crawlers and in your logs. A crawler that hits a loop keeps requesting URLs that keep redirecting. Well-behaved bots detect it and stop; less well-behaved ones don’t, which is where the server-load problem comes from (below).

Why loops matter — three parties get hurt

I frame redirect loops as a three-way problem, because they don’t just cost you rankings — they hit users, bots, and your own infrastructure:

  • For users. They cut off access to the intended resource and trigger a “too many redirects” error in the browser. The page is simply unreachable. This is the headline: it’s a site-outage problem first.
  • For bots and search engines. They trap crawlers and waste crawl budget. A crawler can’t follow a loop to anything indexable, and Google’s own documentation reports this as a “Redirect error” — there’s nothing on the far side of the cycle to crawl through, so there’s nothing to index or rank. It’s not a penalty; the page just functionally can’t be reached. (None of Google’s normal redirect logic — like signals consolidating to a destination over time — applies, because there’s no destination Google ever reaches.)
  • For your server. Loops waste your resources. Some bots detect the loop and back off; others don’t, and a client that keeps re-requesting a looping URL without backing off adds sustained, wasted load. Whether that rises to a serious outage — potentially a self-inflicted DDoS-like event — depends on how much traffic is hitting the loop, whether the responses are cacheable, and your server’s capacity and rate limiting; it isn’t an inherent property of every loop, but it’s a real risk on high-traffic or heavily-crawled sites with no rate limiting in front of them, and it’s an angle most write-ups miss.

Common causes

There’s no single universal cause — every real-world loop traces back to conflicting canonicalization rules across layers that don’t share state. Two different systems each “know” what the correct URL should be, and they disagree, so they bounce the request back and forth. Here are the specific patterns worth checking; which one applies depends on your stack, not a fixed frequency ranking.

HTTP/HTTPS conflict between a CDN and the origin

If you put a proxy/CDN like Cloudflare in front of your site, the connection has two legs: browser → CDN, and CDN → origin. If those two legs disagree about HTTP vs HTTPS, you get a loop entirely at that boundary. Cloudflare’s own troubleshooting doc names this family of causes directly: a misconfigured SSL/TLS Encryption mode, conflicting settings on the Edge Certificates page, or a misconfigured redirect rule — common within Cloudflare’s own product, not necessarily the single most common cause of loops everywhere. A few concrete branches:

  • Flexible mode + origin forces HTTPS. In Flexible SSL mode, Cloudflare talks to your origin over plain HTTP — even though the visitor is on HTTPS. If your origin is also configured to force HTTP → HTTPS (via .htaccess, nginx config, or a plugin): Cloudflare sends HTTP to the origin, the origin says “you must use HTTPS” and redirects, Cloudflare (still Flexible) sends HTTP again, and it repeats forever. Fix: switch Cloudflare to Full or Full (strict) SSL/TLS mode so the CDN→origin leg is also HTTPS (Full strict needs a valid cert on the origin).
  • Full/Full (strict) mode + origin redirects HTTPS → HTTP. Less common, but if the origin has a leftover rule that redirects HTTPS back to HTTP (e.g. from before you enabled Full/strict), the CDN keeps re-requesting over HTTPS and the origin keeps bouncing it to HTTP. Fix: remove the origin-side HTTPS→HTTP rule — the origin should serve HTTPS directly once the CDN is set to Full/strict.
  • “Always Use HTTPS” at the edge plus an origin-level HTTPS redirect. Double-forcing HTTPS at both the edge and the origin (or an HSTS rule fighting a redirect rule) can build the same kind of loop. Fix: pick one place to force HTTPS, not two.
  • A misconfigured redirect rule (a Cloudflare Page Rule, Bulk Redirect, or Transform Rule that sends a URL back toward a form it’s already redirecting away from). Fix: audit edge-level redirect rules for one that contradicts the origin’s own canonicalization.

www / non-www rules that redirect into each other

You want one canonical host — either www.example.com or example.com. A loop happens when one rule sends example.comwww.example.com and another rule (often in a different place — a plugin, a CDN redirect rule, a WordPress “Site Address” setting) sends www.example.comexample.com. Each fires, the other undoes it, forever. Fix: decide on one canonical host, and make sure only one rule (in one place) enforces it, redirecting the other way.

A plugin/CDN rule conflicting with a server/origin rule

The theme running through the causes above is that the loop lives between layers. A WordPress SSL-forcing plugin (or the “WordPress Address” / “Site Address” fields in Settings → General) can disagree with a .htaccess rewrite or a CDN edge rule. Each layer is individually “correct” but they don’t share state, so they fight. “My .htaccess looks fine” doesn’t rule out a loop — the conflicting rule may live at the edge or in a plugin you forgot was there. Fix: find the two rules doing the same job in different places and remove one.

Trailing-slash vs no-trailing-slash logic bugs

A rule that adds a trailing slash (/page/page/) can collide with a rule that strips it (/page//page), producing a loop on that URL. This is usually a single misconfigured rewrite where the condition and the target don’t line up. Fix: decide slash or no-slash, and make the rule only redirect the wrong form to the right one (never redirect a URL to a form that then redirects back).

Leftover, stacked rules from a past migration

Migrations are a common real-world source of loops. HTTP → HTTPS moves, www consolidation, domain changes, and CMS replatforms all involve adding redirect rules — and when you stack a new layer on top of old rules nobody cleaned up, two of them can end up pointing at each other. If a loop appeared “out of nowhere,” check whether a migration left redirect rules behind.

How to diagnose a loop

You want to see the loop, not guess at it.

Trace it from the command line with an actual GET request — not a HEAD-only trace. Send the same kind of request a real visitor or crawler would, and record each status code and Location header without letting curl auto-follow first, so you can see every hop instead of just the final outcome:

# GET is curl's default method (no -I); -L follows redirects; --max-redirs caps how far
curl -sL --max-redirs 10 -D - -o /dev/null https://www.example.com/ | grep -i -E '^(HTTP/|location:)'
# A loop shows the same two (or few) URLs alternating and never a 200 —
# curl stops with "Maximum (10) redirects followed".

To see the effective URL at each stop:

curl -sL --max-redirs 10 -o /dev/null -w '%{http_code} %{url_effective}\n' https://www.example.com/

Then compare against a HEAD-only trace (curl -sIL --max-redirs 10 ...) as a secondary check, not your primary evidence — HEAD and GET are different request methods, and application logic can occasionally handle them differently, so a HEAD-only trace can miss redirect behavior that only shows up on the real request. Never replay unsafe methods (like a form’s POST) just to trace a loop.

If the same host/scheme pair repeats and you never see a 200, that’s the loop — and the two URLs that keep alternating tell you exactly which canonicalization rule is fighting (scheme = HTTP/HTTPS mismatch; host = www/non-www; trailing slash = the slash bug). From there, map each hop to the layer that produced it — browser/HSTS, edge/TLS (CDN), reverse proxy, origin server, application/CMS, or session/auth logic — because a loop happens when two of those layers don’t share state and each insists it’s right.

Other ways in:

  • Browser DevTools → Network tab. Watch the redirect requests stack up before the error, with each Location header visible.
  • Test with and without the CDN. If you can hit the origin directly (bypassing Cloudflare) and it doesn’t loop, the conflict is between the CDN and origin — that points you straight at the SSL-mode cause.
  • Google Search Console. URL Inspection on an affected URL, and the “Redirect error” bucket in the Page Indexing report, tell you which URLs Google is choking on. Google’s Inspection Tools documentation states that Inspection Tools do not follow redirects — so read a URL Inspection result as a report on the exact URL you tested, not as confirmation of what’s on the other side of the loop.
  • A site-wide crawler — Ahrefs’ Site Audit or Screaming Frog — catches loops you don’t know about. In Ahrefs Site Audit: crawl the site (free with an Ahrefs Webmaster Tools account) → Redirects report → Issues tab → look for the “Redirect loop” error, then “View affected URLs” to see the full chain.

How to fix a loop

Once you know the cause, the structural fix is the same decision every time. The best way to fix a loop depends on whether the last URL in the chain — the one right before the loop closes — is the intended final destination:

  • If it is the intended destination: remove the redirect from that final URL, and make sure the resource is actually accessible and returns the correct non-redirect response for that endpoint — usually 200, though the right status depends on the resource (a removed page, for instance, should return its own correct status, not a fake 200).
  • If it isn’t: change the looping redirect to point at the intended final destination instead.

In both cases, also swap out any internal links that point at a redirecting URL for direct links to the final URL — don’t keep feeding the machine URLs that redirect.

Platform-specific fixes:

  • Cloudflare (by SSL mode): move from Flexible to Full or Full (strict) so the CDN→origin leg matches the browser→CDN leg, and don’t force HTTPS at both the edge (“Always Use HTTPS”) and the origin. Full (strict) needs a valid certificate on the origin.
  • WordPress: check Settings → General — “WordPress Address (URL)” and “Site Address (URL)” should match your real canonical scheme/host. Then look for an SSL-forcing plugin (or a FORCE_SSL_ADMIN / redirect snippet in wp-config.php or the theme) that duplicates whatever your server or CDN is already doing, and remove the duplicate. A corrupted .htaccess can also loop — regenerating it from Settings → Permalinks is a common reset.
  • Apache (.htaccess): make sure your HTTPS-forcing and www-forcing RewriteRules have conditions that exclude the already-correct form, so they only redirect the wrong version once.
  • nginx: the same principle — a return 301 for HTTPS or host canonicalization must not fire on requests that are already in the canonical form.

A note on hop limits (the myth to avoid)

Because a loop can look like “too many redirects,” people reach for hop-count solutions — raising max-redirs, bumping a redirect limit in a plugin. That never fixes a true loop. A loop is not a “how many hops is too many” problem the way a long chain is; it fails on the first pass regardless of any hop tolerance, because the cycle never terminates. The only fix is to break the cycle.

A note on Bing

Google formally names “redirect loop” as one of four “Redirect error” causes in its Page Indexing documentation. Bing’s public guidance is more general: use 301s for permanent moves and avoid unnecessary redirect chains. This research didn’t surface a Bing page specifically named “redirect loop” — but that’s a gap in what was checked, not confirmation that Bing has no such guidance anywhere, so treat the four-cause framework above as Google-specific rather than assuming Bing documents loops the same way.

A redirect chain is the sibling problem — a chain that’s too long is a different one of the four “Redirect error” causes, and unlike a loop it does eventually resolve. A 301 redirect is the permanent redirect you’ll usually collapse a loop down to; a 302 redirect is its temporary counterpart. And the redirect error status in Search Console is the GSC report where a loop most often surfaces for SEO purposes.

Add an expert note

Pin an expert quote

New person? Create their unclaimed profile at /admin/experts/ → Pin an expert quote first.