Manually refresh cached content in Varnish Cache

An easy way to do it, when you need it

If for whatever reason you ever need to manually refresh cached content in Varnish, be it an image, a script, some css, or a content page, you can use a nice option of Varnish:

set req.hash_always_miss = true;

How to use that feature?

Simple answer: When you press Ctrl+F5 (Win) or Cmd+R (Mac) in your browser. In almost all browsers by now, your browser reloads the page AND sends a "Cache-Control: no-cache" header with its request. You can use that in Varnish:

1 sub vcl_recv {
2   if (req.http.cache-control == "no-cache") {
3     set req.hash_always_miss = true;
4   }
5 }

How to secure it via IP check

But wait: if you can do it so can someone else do it, which could potentially be harmful, wether intentionally (bad actors) or unintentionally (bad browser extensions, devtools, ...). To get around that you can either limit that feature to certain IPs, like this:

 1 vcl 4.1;
 2 
 3 acl purge {
 4   "123.123.123.123";
 5 }
 6  
 7 sub vcl_recv { 
 8   if (req.http.cache-control == "no-cache" && client.ip ~ purge) {
 9     set req.hash_always_miss = true;
10   }
11 }

How to secure it via obscure custom header

Or you can use a browser extension to modify headers, like this one, to set a custom header like "X-Obscure-Debug-Header". That header will be send only to a predefined domain, with each request. Since it's bound to the same security measures and risks like sending a Basic Auth header, its within most risk tolerance models.

Finally you put that check into your Varnish config:

1 sub vcl_recv {
2   if (req.http.cache-control == "no-cache" && req.http.X-Obscure-Debug-Header) {
3     set req.hash_always_miss = true;
4   }
5 }