How to Fix ERR_TOO_MANY_REDIRECTS — Redirect Loop Fix
The most common cause of ERR_TOO_MANY_REDIRECTS is Cloudflare SSL mode set to "Flexible" combined with an origin server that redirects HTTP to HTTPS. Cloudflare sends HTTP to your origin, your origin redirects to HTTPS, Cloudflare sends HTTP again — infinite loop. Fix: change Cloudflare SSL mode to Full (Strict).
ERR_TOO_MANY_REDIRECTS means the browser followed more than 20 redirects and gave up. Each redirect sent it back to a URL it had already visited — a loop. The fix is always removing one direction of the loop.
Follow your redirect chain — Redirect Chain Fixer →The most common cause: Cloudflare SSL Flexible mode
Cloudflare SSL "Flexible" means Cloudflare connects to your origin over HTTP, even when users connect over HTTPS. If your origin has an HTTP→HTTPS redirect, this creates a loop:
User → HTTPS → Cloudflare → HTTP → Your origin → 301 HTTPS → Cloudflare → HTTP → ...
Fix: change SSL mode to Full (Strict)
Cloudflare Dashboard → SSL/TLS → Overview → Change "Flexible" to "Full (Strict)" # Full (Strict) requires a valid SSL certificate on your origin # Let's Encrypt works — install with Certbot: certbot --nginx -d example.com -d www.example.com
Cloudflare + Vercel loop
Cloudflare Dashboard → SSL/TLS → Overview → Set to "Full" (not Flexible, not Full Strict) # Vercel's certificate is valid — Full mode works correctly
Pure Nginx loop (no CDN)
Two server blocks redirecting to each other, or a return 301 inside the HTTPS block:
# Wrong — causes loop
server { listen 443 ssl; return 301 https://$host$request_uri; # ← redirects to itself
}
# Correct — only the HTTP block redirects
server { listen 80; server_name example.com www.example.com; return 301 https://example.com$request_uri;
}
server { listen 443 ssl; server_name example.com; # NO return 301 here root /var/www/html;
}
Apache loop — missing X-Forwarded-Proto check
# Wrong — fires on HTTPS requests too
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# Correct — only fires on actual HTTP
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Debug with curl (bypasses browser cache)
# Follow the chain and show each hop curl -sIL --max-redirs 10 https://yoursite.com | grep -E "^HTTP|^[Ll]ocation" # If you see the same URL appearing twice, that's the loop
Cookie-caused loops
Some redirect loops only happen in the browser, not in curl. This means a cookie is causing the redirect. Test in an incognito window or clear site cookies — if it works, a cookie is the cause.
Follow your redirect chain →