WordPress is one of the most popular content management systems in the world. It originally started as blogging software, but it has evolved to become a full-blown website building tool (dare I say framework?).
Just like any other CMS and framework, operating WordPress at scale requires a lot of server resources. To reduce the pressure on your application servers and to reduce infrastructure requirements, you can add a caching solution like Varnish.
Because of its power and flexibility, Varnish is very popular in the WordPress community. There are numerous Varnish plugins available for WordPress, which facilitate the integration of Varnish and ensure content is purged from the cache at the right time.
However, when you operate WordPress with Varnish Cache in front of it, you might run into some TLS awareness roadblocks that result in two common issues:
- Mixed content
- The ERR_TOO_MANY_REDIRECTS error
Mixed content
Mixed content means that the output of a web page contains both HTTP and HTTPS URLs. When the browser spots this mix, it considers this page unsafe and returns an error.
Some browsers will automatically upgrade plain HTTP requests to HTTPS requests to reduce the impact of the mixed content. Still, you need to fix this problem.
Mixed content in WordPress is caused by the lack of TLS awareness when a proxy is used.
While Varnish Enterprise, the commercial version of Varnish, has native TLS support, the open source version doesn’t. This means the TLS session needs to be terminated by a TLS Proxy. Meanwhile, Varnish will communicate with WordPress over plain and unencrypted HTTP.
Despite having the ability to set the conventional X-Forwarded-Proto header in Varnish to inform WordPress about the terminated TLS session, WordPress has no built-in support for this header and renders plain HTTP URLs in its output.
The ERR_TOO_MANY_REDIRECTS error
Another TLS-related issue you may encounter when using Varnish in WordPress, is the dreaded ERR_TOO_MANY_REDIRECTS error.
The error implies that your browser has done too many redirection attempts and aborted the execution to prevent an infinite loop.
This issue occurs when WordPress enforces HTTP to HTTPS redirections. This obviously ties into the mixed content issue, because WordPress considers HTTPS requests with terminated TLS nothing more than plain HTTP.
WordPress will keep redirecting, which eventually triggers the ERR_TOO_MANY_REDIRECTS error in the browser.
But even if you would use Varnish Enterprise, which has native TLS support, you would still run the risk of getting stuck in the redirect loop. Varnish will try to cache the response that is returned by WordPress and even redirects end up in the cache.
If the first request for a resource is done over plain HTTP, Varnish will cache the redirection response. Even if the next request is an HTTPS request, the redirection will still be served from the cache.
And that’s because Varnish doesn’t take the request scheme (HTTP or HTTPS) into account when composing the cache lookup hash. Only the request URL and the Host header matter, so there’s no separate cache entry for the HTTPS version of a page.
The solution
The solution to both problems revolves around adding TLS awareness: both in WordPress and in Varnish.
By setting the X-Forwarded-Proto header in Varnish or the TLS proxy, we can make WordPress aware of the terminated protocol. For WordPress to correctly render HTTPS URLs, some minor configuration changes are required in the wp-config.php file.
If that’s not possible, TLS awareness can be configured in your web server. We have example code of how to do this in both Apache and Nginx.
The final piece of the puzzle is setting a Vary: X-Forwarded-Proto header in your web server configuration to inform Varnish that it should take the value of the X-Forwarded-Proto header into account when creating the cache lookup hash. You can even tackle this issue directly in Varnish without changing your web server config.
Read the Varnish Developer Portal tutorial
You now know the context of these TLS-related issues in WordPress and you know what the solution is. However, we haven’t yet explained how to solve them.
We actually created a comprehensive tutorial on the Varnish Developer Portal that explains the problem and the various solutions in detail.