OK, thanks to @jgjh151 sharing his Varnish config file, I think I’ve got this mystery solved.
So…it is definitely an issue with Varnish configuration, but, something also did change in WordPress 3.7, but it was a bug fix. So due to a bug in wp-login.php
in pre-WordPress 3.7, an incorrect configuration in Varnish did not cause any issues with WordPress because the bug in WordPress caused wp-login.php
to not actually check the test cookie.
Here’s the line in Varnish config that’s causing the issue:
if ( (!(req.url ~ "(wp-(login|admin)|login)")) || (req.request == "GET") ) {
It needs to be:
if ( (!(req.url ~ "(wp-(login|admin)|login)")) ) {
Now for the quick explanation. In WordPress 3.6.1 (and earlier I assume), the req.request == "GET"
part of Varnish config was preventing wp-login.php
from writing the test cookie when the form was loaded (called with a GET
), but the code that checked if the test cookie was actually set (when wp-login.php
called via a POST
) never ran if the user’s credentials were good. That is, on the form post, if the user authenticated properly, then the user was redirected to wp-admin without this code being run:
if ( isset($_POST['testcookie']) && empty($_COOKIE[TEST_COOKIE]) )
In WordPress 3.7, this bug in wp-login.php
was fixed, moving the redirect to wp-admin on successful login *after* the cookie check code above. So now the cookie check is actually run. So if Varnish is deleting the test cookie on GET
request to the wp-login.php
, this won’t prevent a login with WordPress 3.6.1 or older, but now that WordPress is actually checking for the test cookie, it will fails the cookie check as it should.
So even though something did change in WordPress, it’s due to misconfiguration of Varnish. (and any other proxy/caching server I imagine)
To use Varnish with WordPress, at least Varnish 3, it’s best to follow the sample template here:
Varnish 3.0 templates – WordPress, Drupal, Joomla and Fork CMS VCL templates
And specifically for WordPress:
fetch/wordpress.vcl
receive/wordpress.vcl