tentmaker.dev Logo tentmaker.dev by Lukas Hermann
Writing

Fixing the ERR_TOO_MANY_REDIRECTS error with Wordpress

··
Updated on
·
  • #php
  • #wordpress
  • #reverse-proxy
  • #error

Every Wordpress developer sooner or later faces the ERR_TOO_MANY_REDIRECTS problem. You navigate to the correct URL but instead of the Wordpress page you are greeted with an error like this (or a similar depending on the browser):

Chrome browser with redirect error

The Problem

(Jump to the solution)

Let’s diagnose

Basically, a miscommunication is happening between your browser and Wordpress that goes something like this:

Simplified chat between browser and web server

You can see this unfold in the network tab of your developer console. In Chrome, hit + alt + I (F12 or Ctrl + Shift + I on Windows) to open the dev tools panel. Go to the “Network” tab, make sure “Preserve log” and “Disable cache” are checked, and then reload the page.

Developer Tools network tab with redirects

You will see that your browser requests the page as instructed but gets a response with status 301 which stands for “permanent redirect” telling your browser that the page you are looking for is actually somewhere else. Let’s open one of the entries in the list and check for the location response header.

Developer Tools network tab showing details about a single redirect

You can see that the location: http://localhost:8081 here is identical to the Request URL: http://localhost:8081. Essentially the browser is asking for http://localhost:8081 but the server is not responding with the page but telling the browser to look in another location. So the browser doesn’t know any better than to ask for the page in this “other” location, which is really the same URL all along. This is called a redirect loop. Eventually, your browser gets tired and gives up with a TOO_MANY_REDIRECTS error.

Note that http://localhost:8081 is a development server on my local computer which I use to reproduce the problem. In your case, it may be https://phaserbeam-computers.com or so.

So why does the server give this response?

In 9 out of 10 cases this problem is caused by a reverse proxy. A reverse proxy is a server that sits in between your browser and Wordpress. This may have a variety of reasons, in my case, it is a webpack dev server, in your case, your hoster may use Nginx as a webserver for its ease and speed but reverse proxy the request to an Apache server so Wordpress can make use of the familiar .htaccess file and the mod_rewrite module.

Whatever the setup, in reality, the above conversation looks more like this:

Simplified chat between browser and webserver with proxy in between

By asking for https://example.com your browser is actually talking to a middleman (the reverse proxy) who then, in turn, asks for the server with Wordpress at another location. Wordpress usually deals with this very well except if the middleman changes the port, then Wordpress seems to panic.

Log in to your webserver via SSH or FTP and add the following lines to your wp-config.php file somewhere above the /* That's all, stop editing! Happy publishing. */ line:

print_r($_SERVER);
die();

With these two lines, we instruct the server to print the $_SERVER variable and then stop any further execution. When you now reload the page you should see some gibberish on the screen that looks like this:

Note: without the die(); the server continues execution of Wordpress’ PHP files and the gibberish we want to see gets drowned by other stuff. By using it we only get the variable dumped on the screen.

Array
(
    [HTTP_X_FORWARDED_HOST] => example.com
    [HTTP_X_FORWARDED_PROTO] => https
    [HTTP_X_FORWARDED_PORT] => 443
    [HTTP_X_FORWARDED_FOR] => 93.184.216.34
    ...
    [HTTP_HOST] => localhost:8000
    [REQUEST_SCHEME] => http
    [SERVER_PORT] => 8000
    [SERVER_ADDR] => 127.0.0.1
    ...
)

In this fictional case, the example.com wordpress site sits behind a reverse proxy. Originally the browser asked for https://example.com on port 443 (the default port for https is 443 and for http is 80). But the reverse proxy forwards the request to some internal server on localhost with port 8000.

Wordpress usually ignores the discrepancy between example.com and localhost but it gets really worked up on the port 8000. See, if Wordpress wants to serve its page securely over HTTPS, something every modern page should do, it will expect https as request scheme and 443 as the port. But it got http and 8000. Thus it thinks the browser did a request for http://example.com and will respond with a “301 Moved Permanently” to https://example.com (note the s in https).

But for your browser, this is exactly the same URL he just asked for.

The Solution

We must tell Wordpress he facts of the original request from the browser before the reverse proxy middleman messed things up for us.

Fortunately, with the HTTP_X_FORWARDED headers, the reverse proxy is kind enough to tell Wordpress what the browser originally asked for. We can look for these headers and then clear things up for Wordpress.

If you have the common problem that you get the redirect error because you want to use the secure HTTPS instead of the insecure HTTP, then add these lines to your wp-config.php:

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

Note: The wp-config.php should be in your Wordpress root directory. Add the PHP snipped somewhere above the /* That's all, stop editing! Happy publishing. */ line

If, however, you are like me and get the error because you are using a webpack dev server or some other more complex setup, this snipped should do the trick:

if (isset($_SERVER['HTTP_X_FORWARDED_HOST']) && isset($_SERVER['HTTP_X_FORWARDED_PORT'])) {
  $_SERVER['HTTP_HOST'] = $_SERVER["HTTP_X_FORWARDED_HOST"];
  $_SERVER['SERVER_PORT'] = $_SERVER["HTTP_X_FORWARDED_PORT"];
}

In any case, it is important to specify exactly at what URL Wordpress is available. You can do this inside the Wordpress settings, but I usually prefer to add these two lines to my wp-config.php:

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

When you debug and test solutions regarding 301 permanent redirects make sure to clear your browser cache or keep the developer tools open with the “Network” tab and “Disable cache” checked.

And with that, you should be good to go.

Your Solution doesn’t work for me

Then your problem is not a reverse proxy or you have an additional misunderstanding within Wordpress. I have seen cases where the redirect loop alternated between https://example.com/ and https://example.com.

Check your plugins and your .htaccess file. To troubleshoot I usually deactivate all plugins and if the error goes away reactivate them one by one until the troublemaker is found.

Read the Let’s diagnose part and check the networks tab of your developer tools to see precisely which redirects the server responds with. Among the response headers, there is also a Server entry that often helps to identify which part of your web server is responsible for the redirect. For example, it may be your “Yoast” plugin.