/ Redirect Checker Fixes / Redirect Loops

How to Fix Redirect Loops

ERR_TOO_MANY_REDIRECTS means two redirect rules are arguing — each thinks the other URL is wrong and tries to redirect to its preferred version. The browser hops between them until it gives up. Almost always a layered-redirect problem: HTTPS forced at proxy AND origin, CDN rule AND .htaccess rule, plugin AND server config. The fix is identifying which two systems are conflicting and disabling the duplicate.

1. Reproduce the loop reliably

Step 1
Browser test in incognito
Incognito ensures no cached redirect or auth state. Visit the affected URL. Browser shows ERR_TOO_MANY_REDIRECTS after ~20 hops.
Step 2
curl trace
curl -IL --max-redirs 10 -v https://example.com/affected-page 2>&1 | \
  grep -E "< HTTP|< Location|> Host"
Shows each hop's status and target. Look for the URL that appears twice — that's where the loop kicks in.
Step 3
Identify the loop pattern
Common patterns:
  • A → B → A (2-hop loop, most common)
  • A → B → C → A (3-hop, rarer)
  • HTTP → HTTPS → HTTP (CDN/origin protocol confusion)
  • www → non-www → www (canonicalisation conflict)

2. Common causes

Cause 1: HTTPS forced at proxy AND origin

# Cloudflare "Always Use HTTPS" page rule: ON
# Origin nginx config:
server {
  listen 80;
  return 301 https://$host$request_uri;
}
# But Cloudflare connects to origin on port 80 (Flexible SSL mode)
# Origin sees HTTP request, redirects to HTTPS
# Cloudflare receives HTTPS redirect, applies its own HTTPS rule (already HTTPS, no change)
# But if Cloudflare connects via HTTP and origin's redirect target is HTTPS via Cloudflare...
# Result: depends on Cloudflare SSL mode

# Fix: set Cloudflare SSL to "Full" or "Full (Strict)" — origin connection uses HTTPS
# Then disable origin's HTTP→HTTPS redirect, let Cloudflare handle it
# OR keep origin's redirect and use Cloudflare "Off" SSL (not recommended)

Cause 2: www canonicalisation conflict

# Cloudflare page rule: www.example.com → example.com (301)
# .htaccess on origin:
RewriteCond %{HTTP_HOST} ^example\.com$
RewriteRule (.*) https://www.example.com/$1 [R=301,L]

# Cloudflare strips www → origin sees non-www → origin adds www → Cloudflare strips again. LOOP.

# Fix: pick one place to do canonicalisation. Disable at the other.

Cause 3: Plugin + .htaccess conflict

# WordPress Redirection plugin: /old-page → /new-page (301)
# .htaccess (forgotten from previous setup):
Redirect 301 /new-page /old-page

# Plugin and .htaccess each pointing the other's source at its target. LOOP.

# Fix: check .htaccess for orphan Redirect/RewriteRule lines. 
# Delete the ones that conflict with plugin-managed redirects.

Cause 4: CDN protocol confusion

# Cloudflare "Flexible SSL": connects to origin via HTTP
# Origin checks: if $scheme != "https" return 301 https://...
# Origin always sees HTTP from Cloudflare, always 301s, infinite loop

# Fix: use X-Forwarded-Proto header instead of $scheme
if ($http_x_forwarded_proto != "https") {
  return 301 https://$host$request_uri;
}
# Origin trusts the header that Cloudflare sets. No loop.

3. The systematic fix

Step 1
List every redirect source
Where can a redirect originate?
  • CDN (Cloudflare page rules, redirect rules, workers)
  • Load balancer (AWS ALB, GCP LB)
  • nginx/Apache server config
  • .htaccess
  • WordPress core (e.g. canonical redirect)
  • SEO plugin (Yoast, Rank Math, AIOSEO)
  • Dedicated redirect plugin (Redirection, Simple 301)
  • Application-level (Express middleware, Django middleware, Rails)
Step 2
Pick one canonical authority per concern
For each redirect type, decide which layer owns it:
  • HTTPS upgrade: CDN (cheapest, fastest)
  • www canonicalisation: CDN
  • Trailing slash: server config
  • Marketing campaign redirects: dedicated plugin or app
  • Permanent URL moves: dedicated plugin or app
Step 3
Disable redirects at all other layers
For HTTPS handled by Cloudflare: comment out the server-level HTTPS redirect. Test. Confirm Cloudflare's redirect still works without origin help.
Step 4
Re-test the loop URLs
curl -IL each URL. Should resolve in 1-2 hops without ERR_TOO_MANY_REDIRECTS.

4. Preventing future loops

Document the redirect ownership

# redirect-ownership.md
# - HTTPS upgrade: Cloudflare → "Always Use HTTPS" page rule
# - www canonicalisation: Cloudflare → page rule www.* → root domain
# - Trailing slash: Origin nginx → return 301 with slash
# - Custom moves: WordPress Redirection plugin
# 
# DO NOT add redirects in .htaccess or origin server config without updating this doc.

Monitor with the Redirect Checker

Schedule weekly scans. Any URL resolving in 3+ hops is a regression. The Redirect Checker alerts on chain length and loops.

5. Edge cases

Edge case: User-Agent-conditional loops

Some sites redirect mobile vs desktop. If detection misfires, you get loops only for certain User-Agents.

# Test with curl mimicking different agents
curl -IL -A "Mozilla/5.0 (iPhone; ..." https://example.com/page
curl -IL -A "Mozilla/5.0 (X11; Linux x86_64) ..." https://example.com/page

# If only one User-Agent loops, the mobile detection logic has a bug.

Edge case: Cookie-conditional loops

Auth or A/B test redirects that depend on cookies can loop when cookies aren't being set properly.

# Reproduce without cookies
curl -IL --cookie-jar /dev/null https://example.com/page

# If clean without cookies but loops with cookies, check cookie-setting on the redirect target.

6. Verify resolution

Step 1
Test in fresh incognito
Affected URLs load without ERR_TOO_MANY_REDIRECTS. Page renders normally.
Step 2
Run the Redirect Checker site-wide
No URLs flagged for loops. Chains all 1-2 hops.
Step 3
Monitor Search Console for crawl errors
"Redirect error" findings in Search Console drop after Google re-crawls (1-4 weeks).
💡 The single rule that prevents most loops: one redirect layer per concern. HTTPS upgrade gets handled at exactly one place. www canonicalisation gets handled at exactly one place. Trailing slash at exactly one place. Document it, enforce in code review.

↪️ Re-run the Redirect Checker

Verify all loops are resolved.

Run Redirect Checker →
Related Guides: Redirect Checker Fixes  ·  Fix Redirect Chains  ·  Fix HTTPS Redirects  ·  Redirect Checker Guide
💬 Got a problem?