I use Nginx > Varnish > Apache, php-fpm in Centos WebPanel.
ERR_TOO_MANY_REDIRECTS
appears for the WordPress homepage only and it goes away and then comes back on my site. This periodical behavior gave the clue that it is a cache-related problem.
Status 301 Moved Permanently
Server nginx/1.16.1
Date Mon, 24 Feb 2020 15:46:29 GMT
Content-Type text/html; charset=iso-8859-1
Content-Length 230
Connection keep-alive
Keep-Alive timeout=60
Location https://thinkbalm.com/
X-Varnish 98379 131369
Age 13
Via 1.1 varnish (Varnish/5.2)
X-Cache HIT from Backend
Setting the domain's configuration to Nginx > Apache, thereby taking out Varnish solves the problem, but then I lose Varnish cache. Therefore I did a lot of searching and the problem seems to be the following:
Varnish and SSL – WordPress Behind an HTTPS Terminating Proxy
Unfortunately, Varnish does not support SSL. So we need to terminate the SSL connection and speak plain HTTP with Varnish and your WordPress site.
Not only does Varnish not support SSL, it is also unaware of the SSL termination and just uses the hostname and the URL of the request as an identifier.
We trigger a problem: forcing HTTPS redirects on an application that is not aware what the initial request protocol, can cause ERR_TOO_MANY_REDIRECTS
errors in your browser.
This happens when the HTTP version of a page is stored in cache. The output is nothing more than a 301 redirect to the HTTPS version. But because Varnish and WordPress are unaware of SSL termination, you’ll end up in a redirection loop until the browser throws this error.
How can we solve this?
I tried adding this to the wp-config
file:
if($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https'){
$_SERVER['HTTPS'] = 'on';
$_SERVER['SERVER_PORT'] = 443;
}
I also tried to add this to .htaccess:
SetEnvIf X-Forwarded-Proto "https" HTTPS=on
Header append Vary: X-Forwarded-Proto
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTPS} !=on
RewriteCond %{HTTP:X-Forwarded-Proto} !https [NC]
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IfModule>
None of these resolved the situation.
Any ideas?
Best Answer
The entire solution, which I wrote a blog post about, depends on the presence of the
X-Forwarded-Proto
header.HTTPS
environment variable cannot be set in Apache.My initial assumption is that this header is not properly set. But there's an easy way to find out:
Please send me the output of the following Varnish command:
I'm assuming this happens on the homepage, so the command filters for requests on the homepage.
Please also confirm if you have a custom
sub vcl_hash
configuration that influences the way cache variations are done.