Guides

8 min readUpdated

ERR_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.

A redirect loop traced with curl 7.88.1 (captured on a local test setup using the reserved name example.test; the routing and test-CA options are omitted)
$ 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.

PatternWhat the trace showsCauseFix
HTTPS loop behind a proxyThe same https URL, over and overThe proxy talks to the origin over HTTP and the origin forces HTTPSEncrypt the origin connection, or have the origin trust X-Forwarded-Proto
HTTPS and HTTP ping-ponghttps and http URLs take turnsThe edge forces HTTPS while the origin or CMS still forces HTTPRemove the origin's redirect to HTTP and update the site URL
www and bare domain ping-pongwww and non-www take turnsA CDN rule prefers one name, the server or CMS the otherPick one canonical name and set it everywhere
Redirect inside the HTTPS serverThe same https URL, even without a proxyAn unconditional redirect to HTTPS in a server block that also serves HTTPSRedirect only in the port 80 server
Login or cookie loopThe login page and the target page take turnsA cookie is not stored or not sent back: a Secure cookie over HTTP, the wrong cookie domain, blocked cookies, or a stale cookieClear the site's cookies; fix the cookie domain and flags
Cached old redirectcurl shows no loop, but one browser still loopsA 301 cached by the browser or the CDNClear 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 withOrigin ruleResult
HTTP (Cloudflare's Flexible mode)Redirects HTTP to HTTPSLoop
HTTPNo redirect, or a redirect only when X-Forwarded-Proto is httpWorks, but the origin leg is unencrypted
HTTPS (Full or Full strict)Redirects HTTP to HTTPSWorks: the origin sees HTTPS
HTTPSRedirects HTTPS to HTTPLoop
The edge forces HTTPS for visitorsRedirects HTTPS to HTTPLoop
nginx on both sides: the proxy reports the scheme, the origin redirects only real HTTP requests (checked with nginx -t and live requests on nginx 1.22.1)
# 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 lines adapted from the WordPress handbook (an isset check added), and WP-CLI commands; not executed on the test machine
// 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

Chrome stops after 20 redirects for a single request, the limit the Fetch standard sets for browsers, and Firefox's default limit is also 20. curl allows 50 unless you change it with --max-redirs. Search crawlers are stricter: Google's documentation says its crawlers follow up to 10 redirect hops. A well-configured site needs one or two hops at most, from the typed address to the canonical URL.

Sometimes. If the loop is caused by a stale or rejected cookie, for example after a login change or a consent banner update, deleting that site's cookies ends it. If the loop comes from the server or CDN configuration, clearing cookies changes nothing and the page loops on every device. A quick test is a private window: if the site works there, cookies or cached redirects are to blame.

Most often because the CDN connects to the origin over plain HTTP while the origin redirects every HTTP request to HTTPS. The origin never sees HTTPS, so it redirects every time. Switch the CDN to connect over HTTPS with a valid origin certificate, or make the origin's redirect depend on the X-Forwarded-Proto header, and remove duplicate HTTPS redirects so that only one layer issues them.

Yes, if it lasts. Crawlers that never reach a page cannot index it, and Search Console reports failed redirects as errors. Google's crawlers follow up to 10 redirect hops, so even a long chain that eventually resolves can fail. Fix the loop, keep redirects to one or two hops, and point internal links and sitemaps at the final URL rather than at an address that redirects.

Because that browser kept something the others did not: a cookie that triggers a redirect, or a 301 it cached on an earlier visit. A cached 301 can outlive the server configuration that sent it, so a fixed server can still loop in that browser. Delete the site's data there or test in a private window; curl, which keeps no cache, shows what the server does now.

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.

  1. 01url_request.h: kMaxRedirects = 20 · Chromium
  2. 02error_page_strings.grdp: "redirected you too many times" · Chromium
  3. 03Fetch Standard: HTTP-redirect fetch (redirect count 20) · WHATWG
  4. 04Firefox default preferences: network.http.redirection-limit · Mozilla
  5. 05Firefox network error page strings · Mozilla
  6. 06curl man page: --max-redirs and exit code 47 · curl
  7. 07ERR_TOO_MANY_REDIRECTS · Cloudflare docs
  8. 08SSL/TLS encryption modes · Cloudflare docs
  9. 09HTTPS: using a reverse proxy · WordPress Developer Resources
  10. 10Editing wp-config.php: WP_HOME and WP_SITEURL · WordPress Developer Resources
  11. 11wp option update · WP-CLI
  12. 12Apache mod_rewrite: RewriteCond and %{HTTP:header} · Apache HTTP Server
  13. 13Module ngx_http_proxy_module: proxy_set_header · nginx.org
  14. 14RFC 9110, HTTP Semantics, section 15.4: Redirection 3xx · RFC Editor
  15. 15How HTTP status codes affect Google's crawlers · Google Search Central

Last updated