Guides
8 min readUpdatedERR_TOO_MANY_REDIRECTS: how to find and break a redirect loop
Quick answer
ERR_TOO_MANY_REDIRECTS means the site sent Chrome round in a circle: each response redirected to a URL that redirected again, until Chrome stopped after 20 hops. The browser is fine; the loop comes from server, CMS or proxy settings that disagree. The classic case behind a CDN or reverse proxy is an origin that forces HTTPS while the proxy talks to it over plain HTTP. One curl command shows the loop and the rule behind it.
01What does ERR_TOO_MANY_REDIRECTS mean?
Chrome shows the error under the heading "This page isn't working", with the line "example.com redirected you too many times". Every response the browser received was a redirect, a 3xx status code with a Location header, and following them never reached a page. Chromium allows 20 redirects per request, the limit the Fetch standard sets for browsers. Firefox's default is also 20, and command-line curl stops after 50.
Usually no single server is broken. Each one answers correctly by its own rules; the rules just disagree. A proxy says "use HTTPS", the origin behind it never sees HTTPS and says the same again, and the browser goes round until it hits the limit.
02How do I see the redirect loop?
Use curl, which caches nothing and prints every hop. The first command lists the status line and Location header of each response; the second prints how far curl got. curl exits with code 47 when it reaches the limit you set.
The trace has one of two shapes. If the Location is the URL you just requested, the server does not see the request the way the browser sent it, almost always the scheme behind a proxy. If two Locations take turns, two rules disagree, typically www against the bare domain, or HTTP against HTTPS.
$ curl -sIL --max-redirs 5 https://example.test/ | grep -iE '^(HTTP|location)'
HTTP/1.1 301 Moved Permanently
Location: https://example.test/
HTTP/1.1 301 Moved Permanently
Location: https://example.test/
# ... the same pair four more times
$ curl -s -o /dev/null -L --max-redirs 5 -w '%{num_redirects} redirects, last %{http_code} to %{redirect_url}\n' https://example.test/; echo "exit $?"
5 redirects, last 301 to https://example.test/
exit 47
# a www ping-pong looks different: two Locations take turns
Location: https://www.example.test/
Location: https://example.test/
Location: https://www.example.test/03What causes too many redirects?
Most redirect loops follow one of six patterns, and the trace usually shows which within seconds.
| Pattern | What the trace shows | Cause | Fix |
|---|---|---|---|
| HTTPS loop behind a proxy | The same https URL, over and over | The proxy talks to the origin over HTTP and the origin forces HTTPS | Encrypt the origin connection, or have the origin trust X-Forwarded-Proto |
| HTTPS and HTTP ping-pong | https and http URLs take turns | The edge forces HTTPS while the origin or CMS still forces HTTP | Remove the origin's redirect to HTTP and update the site URL |
| www and bare domain ping-pong | www and non-www take turns | A CDN rule prefers one name, the server or CMS the other | Pick one canonical name and set it everywhere |
| Redirect inside the HTTPS server | The same https URL, even without a proxy | An unconditional redirect to HTTPS in a server block that also serves HTTPS | Redirect only in the port 80 server |
| Login or cookie loop | The login page and the target page take turns | A cookie is not stored or not sent back: a Secure cookie over HTTP, the wrong cookie domain, blocked cookies, or a stale cookie | Clear the site's cookies; fix the cookie domain and flags |
| Cached old redirect | curl shows no loop, but one browser still loops | A 301 cached by the browser or the CDN | Clear the browser cache or purge the CDN |
04Why redirect loops happen behind a CDN or reverse proxy
The classic loop after putting a site behind a CDN or reverse proxy runs in four steps. It was reproduced exactly with nginx on both sides for the trace above.
- 1. The browser requests https://example.com/ from the edge, which terminates TLS.
- 2. The edge forwards the request to the origin over plain HTTP on port 80.
- 3. The origin sees an HTTP request, applies its rule to always use HTTPS, and answers 301 to https://example.com/.
- 4. The edge passes the 301 back, the browser requests the same URL again, and the cycle repeats until Chrome stops at 20.
| Edge connects to the origin with | Origin rule | Result |
|---|---|---|
| HTTP (Cloudflare's Flexible mode) | Redirects HTTP to HTTPS | Loop |
| HTTP | No redirect, or a redirect only when X-Forwarded-Proto is http | Works, but the origin leg is unencrypted |
| HTTPS (Full or Full strict) | Redirects HTTP to HTTPS | Works: the origin sees HTTPS |
| HTTPS | Redirects HTTPS to HTTP | Loop |
| The edge forces HTTPS for visitors | Redirects HTTPS to HTTP | Loop |
# on the proxy
location / {
proxy_pass http://203.0.113.10;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
}
# on the origin
server {
listen 80;
server_name example.com;
if ($http_x_forwarded_proto = "http") {
return 301 https://$host$request_uri;
}
root /var/www/example;
}05How to fix too many redirects in WordPress
WordPress stores two addresses, home and siteurl, and redirects requests that arrive under another address. If either still says http:// or the wrong host after a move to HTTPS or behind a proxy, WordPress and the server can redirect each other indefinitely. Both must match the canonical URL exactly, scheme and www included.
Behind a proxy that terminates TLS, WordPress also needs to know the original request was HTTPS. The WordPress handbook warns that, without this, its HTTPS-forcing options on a site behind an SSL-providing reverse proxy "will initially send any requests into an infinite redirect loop", and gives a wp-config.php fix based on X-Forwarded-Proto. If the loop persists, disable redirect and SSL plugins by renaming their folders in wp-content/plugins, then re-enable them one by one. The WordPress WAF guide covers running WordPress behind a proxy safely.
// wp-config.php, above the "stop editing" comment
if ( isset( $_SERVER['HTTP_X_FORWARDED_PROTO'] )
&& strpos( $_SERVER['HTTP_X_FORWARDED_PROTO'], 'https' ) !== false ) {
$_SERVER['HTTPS'] = 'on';
}
define( 'WP_HOME', 'https://example.com' );
define( 'WP_SITEURL', 'https://example.com' );
# or read and correct the stored values with WP-CLI
wp option get home
wp option get siteurl
wp option update home 'https://example.com'
wp option update siteurl 'https://example.com'06How to fix ERR_TOO_MANY_REDIRECTS as a visitor
If the loop comes from the site's configuration, only the owner can fix it, but two causes do live in the browser: a stale cookie and a cached redirect. Firefox's own error page notes that the problem "can sometimes be caused by disabling or refusing to accept cookies".
- Delete the cookies and site data for that one site, from the site information icon left of the address or in Chrome's site settings, then reload.
- Open the page in a private window. If it loads there, the cause is a cookie, a cached redirect or an extension.
- Turn off extensions that rewrite or upgrade URLs, such as HTTPS-only or privacy tools, and retry.
- Allow cookies for the site if you block them; login pages often redirect until a cookie can be set.
- If it fails on every device and network, tell the site owner, with the exact URL.
07Server-side checks, in order
Find which layer issues each redirect before changing anything; the Server and Via headers of each hop in the full curl -sIL output often name it. Then work from the outside in.
- Check the CDN or proxy first: forced-HTTPS settings, redirect rules, and the mode it uses to reach the origin.
- Then the web server: nginx return and rewrite lines, and Apache RewriteRule lines in the configuration or .htaccess.
- On Apache behind a TLS-terminating proxy, RewriteCond %{HTTPS} off is always true, because Apache only sees HTTP; test RewriteCond %{HTTP:X-Forwarded-Proto} !https instead.
- Then the application: the site URL setting, framework options that trust proxy headers, and redirect plugins.
- After the fix, purge the CDN cache and retest with curl. RFC 9110 lets clients cache a 301, so a browser may keep looping until its cache is cleared.
08What a reverse proxy can and cannot do about redirect loops
A proxy or CDN can remove the most common loop entirely. It can redirect HTTP to HTTPS at the edge, so the origin needs no redirect of its own, pass X-Forwarded-Proto to the origin, and encrypt the origin connection so the origin sees HTTPS natively.
It cannot fix rules it does not own. A WordPress site URL set to http://, a plugin that forces a different host, a cookie the application never manages to set, or a 301 already cached in a visitor's browser keep looping however the edge is configured. The lasting fix is to make exactly one layer responsible for each redirect.
Questions
Frequently asked questions
Sources
Sources and verification
Loop traces reproduced with curl 7.88.1 against local nginx 1.22.1 test servers on Debian 12, October 2026: a TLS-terminating proxy in front of an HTTPS-forcing origin, a www and bare-domain ping-pong, and a redirect inside an HTTPS server block. The nginx fix was checked with nginx -t and live requests. The WordPress lines follow WordPress documentation and were not executed.
- 01url_request.h: kMaxRedirects = 20 · Chromium
- 02error_page_strings.grdp: "redirected you too many times" · Chromium
- 03Fetch Standard: HTTP-redirect fetch (redirect count 20) · WHATWG
- 04Firefox default preferences: network.http.redirection-limit · Mozilla
- 05Firefox network error page strings · Mozilla
- 06curl man page: --max-redirs and exit code 47 · curl
- 07ERR_TOO_MANY_REDIRECTS · Cloudflare docs
- 08SSL/TLS encryption modes · Cloudflare docs
- 09HTTPS: using a reverse proxy · WordPress Developer Resources
- 10Editing wp-config.php: WP_HOME and WP_SITEURL · WordPress Developer Resources
- 11wp option update · WP-CLI
- 12Apache mod_rewrite: RewriteCond and %{HTTP:header} · Apache HTTP Server
- 13Module ngx_http_proxy_module: proxy_set_header · nginx.org
- 14RFC 9110, HTTP Semantics, section 15.4: Redirection 3xx · RFC Editor
- 15How HTTP status codes affect Google's crawlers · Google Search Central
Last updated