How to fix ERR_TOO_MANY_REDIRECTS

Two rules are sending visitors back and forth forever. Usually HTTP and HTTPS, or www and non-www, set differently in two places.

3–5 minutes
Dense bundle of patch cables in a network rack

ERR_TOO_MANY_REDIRECTS means the page redirected your browser, and the next page redirected it again, round and round, until the browser gave up after about 20 hops. On the site’s side it is almost always two settings disagreeing: one sends visitors to HTTPS and another sends them back to HTTP, or one adds www and another removes it.

Firefox calls the same problem The page isn’t redirecting properly, and Safari Too many redirects occurred.

If you are visiting the site

Clear the cookies for that one site: old login or preference cookies can trigger a loop. In Chrome, click the icon left of the address, then Cookies and site data > Manage on-device site data, and delete the site’s entries. Then reload. If it still loops, try a private window; if that loops too, the problem is on the site and only the owner can fix it.

See the loop

Before changing anything, look at the chain of redirects. curl shows every hop:

curl -sIL https://example.com/ | grep -iE "^HTTP|^location"

A typical loop looks like this:

HTTP/2 301
location: http://example.com/
HTTP/1.1 301 Moved Permanently
Location: https://example.com/
HTTP/2 301
location: http://example.com/

The site sends HTTPS visitors to HTTP, and HTTP visitors to HTTPS. The location values tell you which two rules are fighting.

If you run the site

1. HTTPS behind a CDN or proxy (the most common cause)

With Cloudflare set to Flexible SSL mode, visitors connect to Cloudflare over HTTPS, but Cloudflare connects to your server over plain HTTP. Your server sees an HTTP request and redirects to HTTPS. Cloudflare passes that redirect back, the browser asks for HTTPS again, and the loop is complete.

The fix is to set Cloudflare’s SSL mode to Full (strict), with a valid certificate on your server. Flexible mode is the cause of a large share of all redirect loops; avoid it.

The same loop happens behind any load balancer that ends HTTPS and forwards plain HTTP. In that case, redirect based on the header the balancer adds, not on the connection your server sees:

# Nginx behind a load balancer
if ($http_x_forwarded_proto = "http") {
    return 301 https://$host$request_uri;
}

2. WordPress addresses disagree with the server

WordPress redirects every request to the address set in Settings > General. If that says http:// but the server forces HTTPS, or says www.example.com while the server strips www, they loop. Check the stored values:

wp option get home
wp option get siteurl

If you cannot reach the admin area, set them in wp-config.php, which overrides the database:

define( 'WP_HOME', 'https://example.com' );
define( 'WP_SITEURL', 'https://example.com' );

Behind a proxy that ends HTTPS, WordPress may not know the visitor used HTTPS and keeps redirecting. Add this to wp-config.php, above the That’s all, stop editing line:

if ( isset( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) && 'https' === $_SERVER['HTTP_X_FORWARDED_PROTO'] ) {
    $_SERVER['HTTPS'] = 'on';
}

3. Two layers both redirecting

Redirects can be set in many places: the Nginx or Apache configuration, .htaccess, a WordPress plugin (Really Simple SSL, Redirection, an SEO plugin), the control panel, and the CDN’s page rules. Two of them with different ideas of the “right” address cause a loop. Search the server:

grep -RnE "return 30[12]|rewrite .* (permanent|redirect)" /etc/nginx/
grep -nE "Redirect|RewriteRule" /var/www/example.com/public/.htaccess

Pick one place to own each decision (HTTPS, and www or not) and remove the rule from the others. The web server configuration is the most reliable place.

A clean Nginx setup sends everything to one address, once:

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;
}

The main server block for example.com on port 443 then has no redirect at all.

4. A redirect plugin or rule pointing at itself

A redirect from /page to /page/, combined with a rule that strips trailing slashes, loops on that page only. If only some pages loop, check redirect plugins and page rules for the affected address.

5. Cookies and caches

Browsers cache permanent (301) redirects. After fixing the server, your own browser may keep looping on its cached redirect. Test with curl or a private window, which use no cache. A page cache or CDN can also keep serving an old redirect: purge it after changing redirect rules.

Confirm it is fixed

curl -sIL http://www.example.com/ | grep -iE "^HTTP|^location"

You want at most one or two redirects, ending in HTTP/2 200 at the address you chose. Test all four combinations: http and https, with and without www.

Something out of date? Software changes. If a step no longer works, tell us and we will check it and update the page.