ERR_TOO_MANY_REDIRECTS: find the loop and fix it
The browser gave up because the site kept sending it somewhere else, and that somewhere sent it back. The loop is almost always two rules that disagree, and one command shows you both.
What the browser is telling you
Chrome shows This page isn’t working: example.com redirected you too many times. ERR_TOO_MANY_REDIRECTS; Firefox says The page isn’t redirecting properly; Safari says Too many redirects occurred. Each browser follows about 20 redirects in a row, then stops. Nothing is “down”: every response is a valid 301, 302, 307 or 308 (what each redirect code means), they just form a circle.
See the loop
curl -sIL --max-redirs 10 https://example.com/ | grep -iE "^(HTTP|location)"
HTTP/2 301
location: https://example.com/
HTTP/2 301
location: https://example.com/
...
Read the location lines. The pattern tells you the cause:
| Loop pattern | Usual cause |
|---|---|
| https:// to the same https:// URL, again and again | The origin thinks the request is plain HTTP (Cloudflare Flexible SSL, or a proxy without X-Forwarded-Proto) |
| http:// and https:// alternating | One layer forces HTTPS while another forces HTTP (an old rule, a CMS site URL set to http) |
| www and non-www alternating | The CDN or DNS rule prefers one, the server or CMS prefers the other |
/page and /page/ alternating | Two trailing-slash rules disagree (framework vs server vs host) |
Bouncing to /login and back | A login cookie isn’t being saved or sent (wrong domain, Secure cookie over http, SameSite) |
If curl shows no loop but the browser still does, it’s probably cookies or a cached 301: try a private window, or clear the site’s cookies and cache. Browsers remember 301s and 308s hard.
Cloudflare Flexible SSL (the classic)
With Flexible, Cloudflare talks to your server over plain HTTP. Your server sees http, redirects to https, the visitor comes back through Cloudflare, which again talks http to your server… forever. Fix: install a certificate on the origin (a free Cloudflare Origin Certificate is fine) and set SSL/TLS to Full (strict). Also check you don’t have both “Always Use HTTPS” and a redirect rule pointing the other way.
Behind a load balancer or reverse proxy
TLS ends at the proxy, so the app receives plain HTTP and thinks it must redirect. Make the proxy send X-Forwarded-Proto: https and tell the app to trust it:
# nginx in front of the app
proxy_set_header X-Forwarded-Proto $scheme;
# Express
app.set('trust proxy', 1);
# Django settings.py
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
# Flask
from werkzeug.middleware.proxy_fix import ProxyFix
app.wsgi_app = ProxyFix(app.wsgi_app, x_proto=1, x_host=1)
# Rails config/environments/production.rb
config.assume_ssl = true # with config.force_ssl = true
WordPress
- Settings, General: WordPress Address and Site Address must both be the same scheme and host (both
https://www.…or both without www). If you’re locked out, set them inwp-config.phpwithdefine('WP_HOME', 'https://example.com');anddefine('WP_SITEURL', 'https://example.com');. - Behind a proxy or Cloudflare, add
if (($_SERVER['HTTP_X_FORWARDED_PROTO'] ?? '') === 'https') $_SERVER['HTTPS'] = 'on';near the top ofwp-config.php. - Temporarily rename the
pluginsfolder to rule out an SSL or redirect plugin fighting the server.
nginx and .htaccess rules
Redirect only when the request really is http, and keep the HTTPS server block free of the redirect:
server { listen 80; server_name example.com www.example.com;
return 301 https://example.com$request_uri; }
server { listen 443 ssl; server_name www.example.com;
return 301 https://example.com$request_uri; }
server { listen 443 ssl; server_name example.com; # the real site, no redirect here
... }
Pick one canonical host and one trailing-slash style, and make every layer (CDN, server, app) agree with it. A quick way to compare long redirect URLs that differ only in encoding is to paste them into the URL encoder/decoder. If the browser never connects because DNS fails, that is ERR_NAME_NOT_RESOLVED, not a redirect loop; TLS confusion after a bad redirect is covered in ERR_SSL_PROTOCOL_ERROR.
Related
Questions
What causes ERR_TOO_MANY_REDIRECTS?
Two redirect rules that disagree, so each request is sent back to a URL that redirects again. The most common causes are Cloudflare Flexible SSL with an HTTPS redirect on the server, an app behind a proxy that doesn't trust X-Forwarded-Proto, and www vs non-www or trailing-slash rules that conflict.
How do I fix too many redirects on Cloudflare?
Put a certificate on your origin server and change SSL/TLS encryption mode from Flexible to Full (strict). Flexible makes Cloudflare connect over plain HTTP, so an origin that redirects HTTP to HTTPS loops forever.
Does clearing cookies fix too many redirects?
Only when the loop is caused by a cookie, such as a login session that is not being stored. Browsers also cache 301 and 308 redirects, so test in a private window after fixing the server.
How many redirects does a browser allow?
Chrome and Firefox stop after 20 redirects in a row; Safari has a similar limit. curl -L follows up to 50 unless you set --max-redirs.
Published .