Guides 11792 Published by

Stopping NGINX from sending the ETag header is a quick way to force browsers to reload every file and avoid stale caches that can leave users staring at old images or PDFs. The article walks you through adding `etag off;` in either the global http block or a specific server block, plus how to strip upstream ETags with `proxy_hide_header` and an empty `add_header`. It also covers testing steps—running `nginx -t`, gracefully reloading, and verifying the header’s absence with curl or dev‑tools. Finally, it cautions about common pitfalls such as editing the wrong config file, reverse‑proxy headers leaking, and the difference between static files served by NGINX and dynamic responses that must be handled at the application level.



How To Disable ETag in NGINX – A Quick Fix for Stale Browser Caches

In a few clicks you can stop NGINX from sending the ETag header that tricks browsers into thinking they already have the latest file. The result? Fresh content on every hit, no more “old picture still showing” complaints.

Why Disable ETag?

ETags are a double‑edged sword.

On one hand, they let browsers avoid re‑downloading files it thinks haven’t changed. On the other, in a world of CDN edge caches and aggressive client caching, they can lock users into an older version until you force a purge or hit a cache‑busting query string.

I once had a corporate intranet where employees kept seeing the old PDF after we updated it. Even though the file size changed, browsers still served the cached copy because of its ETag. Turning off ETags made the browser revalidate every request and resolved the issue in seconds.

Where to Put It

Open your site’s NGINX configuration – usually /etc/nginx/sites-available/default or a file under /etc/nginx/conf.d/.

Add etag off; inside the http block (global) or inside a specific server block if you only want it for one virtual host.

http {
    # …other global settings…

    etag off;

    server {
        listen 80;
        server_name example.com;

        root /var/www/html;
        # other server‑specific directives…
    }
}

Adding it to the http block disables ETag for all sites on that NGINX instance.

If you’re proxying upstream services, you might also want to strip any ETag coming from them:

proxy_hide_header ETag;
add_header ETag "" always;
Testing Your Change

1. Validate the syntax – run sudo nginx -t.

If it reports “syntax is ok” and “test failed”, you’ll see exactly what’s wrong.

2. Reload NGINX – sudo systemctl reload nginx (or nginx -s reload).

No downtime, just a graceful restart.

3. Verify the header – use curl or your browser dev tools:

curl -I http://example.com/index.html | grep ETag

You should see nothing back. If you still see an ETag, double‑check that you edited the right file and reloaded correctly.

Common Pitfalls
  • Wrong config file – NGINX may be pulling from /etc/nginx/conf.d/*.conf or a custom include. Use nginx -T | grep etag to find where the setting is applied.
  • Cached reverse‑proxy headers – If you’re behind another proxy, its ETag can still reach the client unless you hide it with proxy_hide_header.
  • Static vs dynamic content – The etag off; directive only affects static files served directly by NGINX. Dynamic responses (e.g., from PHP or Node) must be handled at the application level.

That’s it—now your browsers will fetch fresh content instead of being stuck in a stale loop.