ERR_TOO_MANY_REDIRECTS: What Causes It and How to Fix It (Including Cloudflare)
"This page isn't working — redirected you too many times." The usual causes of a redirect loop — Cloudflare's Flexible SSL mode, conflicting www rules, an app that doesn't know it's behind a proxy, and login loops — and how to find and fix each.
You open your site and the browser says:
This page isn't working. example.com redirected you too many times. ERR_TOO_MANY_REDIRECTS
It means your site is stuck in a redirect loop: page A sends the browser to page B, and B sends it straight back to A, forever. The browser gives up after about 20 hops.
The good news: there are only a handful of usual causes.
Step 0: Rule out old cookies
Occasionally a stale cookie causes a login redirect loop. Try a private window. If the site works there, clear cookies for that domain and you're done. If not, read on.
Step 1: See the loop
Find out exactly what's redirecting where. In a terminal:
curl -sIL https://example.com | grep -iE "^(HTTP|location)"
You'll see each hop:
HTTP/2 301
location: http://example.com/
HTTP/1.1 301
location: https://example.com/
HTTP/2 301
location: http://example.com/
...
Here, HTTPS goes to HTTP and back again — the classic proxy loop. Alternatively, open DevTools, go to the Network tab, tick "Preserve log", and load the page. (HTTP status codes explained covers 301 and 302.)
Cause 1: Cloudflare "Flexible" SSL (the most common)
If you use Cloudflare's proxy (the orange cloud), check SSL/TLS → Overview. In Flexible mode:
- Visitors connect to Cloudflare over HTTPS.
- Cloudflare connects to your server over plain HTTP.
- Your server (or host) says "this request came over HTTP — redirect to HTTPS!"
- The browser requests HTTPS again… back to step 1.
Fix: set Cloudflare's SSL mode to Full (strict), so Cloudflare connects to your server over HTTPS. Your server needs a valid certificate for that — most hosts provide one automatically (how automatic SSL works). Avoid Flexible mode; it also means traffic between Cloudflare and your server isn't encrypted.
Cause 2: Conflicting www rules
Your host redirects www.example.com → example.com, while a DNS-level or proxy rule redirects example.com → www.example.com. They bounce visitors between each other.
Fix: decide on one canonical version and make sure only one place enforces it. See www vs non-www.
Cause 3: Your app doesn't know it's behind a proxy
Your app runs behind a reverse proxy or load balancer that handles HTTPS and forwards plain HTTP to the app. The app sees HTTP and redirects to HTTPS — which arrives at the app as HTTP again.
Proxies send a header saying what the original protocol was: X-Forwarded-Proto: https. The app must be told to trust it:
- Express:
app.set("trust proxy", 1) - Django:
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https") - Laravel: configure trusted proxies.
Alternatively, remove the app's own HTTPS redirect and let the proxy handle it — one place, not two.
Cause 4: Login redirect loops
Your middleware redirects logged-out users to /login… and the /login page itself is protected by the same middleware. Or the login succeeds but the session cookie isn't saved (often because it's marked Secure while the app thinks it's on HTTP — see cause 3), so the app redirects back to login.
Fix: exclude /login (and static assets) from the auth check, and confirm the session cookie is actually set in DevTools → Application → Cookies. (Cookies explained.)
Cause 5: A redirect rule pointing at itself
A rule like "redirect /blog to /blog/" combined with a framework rule that strips trailing slashes. Each undoes the other.
Fix: check redirects in your host's settings, your framework config (next.config.js, .htaccess, Nginx config), and your DNS/proxy provider. Remove duplicates so each redirect lives in exactly one place.
A rule that prevents most loops
Every redirect should be decided in one layer. HTTPS enforcement, www handling and trailing slashes each belong to either the proxy, the host or the app — not several at once. Most loops come from two layers each trying to be helpful.
The summary
- ERR_TOO_MANY_REDIRECTS is a loop: A → B → A.
- Trace it with
curl -sILor the Network tab to see each hop. - Usual causes: Cloudflare Flexible SSL, conflicting www rules, an app not trusting
X-Forwarded-Proto, login loops, duplicate slash rules. - Enforce each kind of redirect in exactly one place.
EasySpawn serves your app over HTTPS on your own domain with certificates handled automatically — and Claude Code can trace a redirect loop with curl on the server itself and fix it where it starts. See how it works or join the waitlist.
Related: Mixed Content Errors · What Is HTTPS? · DNS Records Explained · Why Does My App Work Locally but Not in Production? · Cloudflare Proxied vs DNS Only
Keep reading
"Your Connection Is Not Private" on Your Own Site: Causes and Fixes
When visitors see NET::ERR_CERT_DATE_INVALID, ERR_CERT_COMMON_NAME_INVALID or ERR_CERT_AUTHORITY_INVALID on your site, the SSL certificate is expired, for the wrong name, or incomplete. How to tell which, and how to fix each one.
Why Is My Environment Variable Undefined? (Vite, Next.js, Node)
Your .env file has the value but the code sees undefined. The reasons are almost always the same: the wrong prefix (VITE_, NEXT_PUBLIC_), the wrong file name or folder, not restarting the dev server, build-time vs runtime, or the variable never being set in production.