2

In modern versions of Nginx, the ETag is automatically generated for static file types, even if you don't specifically enable the etag on in your location blocks or otherwise:

https://nginx.org/en/docs/http/ngx_http_core_module.html#etag

For example, your PNG or JPEG files served by Nginx will automatically include the HTTP headers for content-length, last-modified, and etag on static files that are not gzipped even if you don't manually enable them...

However, what file types does Nginx do this for by default? When I tested this by including .html file extensions in my static files location block, and manually added etag on to all of my "static" file types (including .html files, even though they are not typically considered static), Nginx stripped out the etag HTTP header for my .html files (even though it was hardcode enabled in the location block) but not other file types such as PNG or JPEG.

Update: it was Cloudflare stripping out the etag header on my .html files and not Nginx. However, Nginx does strip the content-length header when gzip is enabled on certain file types. To make matters more confusing, Cloudflare adds gzip on some content automatically.

I don't see any documentation about this... which files types will Nginx automatically enable ETags for, and which file types will Nginx ignore/strip ETags for by default?

Edit: These gzip related discussion might be related:

https://javorszky.co.uk/2019/03/28/etag-if-match-nginx-and-you/

https://forum.nginx.org/read.php?2,286645,286645#msg-286645

https://forum.nginx.org/read.php?2,240120,240120#msg-240120

https://stackoverflow.com/questions/55305687/how-to-address-weak-etags-conversion-by-nginx-on-gzip-compression

TIL that Nginx strips weak ETags from upstream responses when gzipping them for "Accept-Encoding: gzip". Thanks, internet.

https://twitter.com/tomstuart/status/367994690517225472

6
  • Please share your full configuration as shown by nginx -T. Commented Sep 5, 2022 at 19:03
  • Thanks @TeroKilkanen but this is meant to be a generic question, it's not really a case specific error but seeking documentation. Commented Sep 5, 2022 at 19:20
  • Are you sure that your configuration doesn't affect the behavior in any way? Commented Sep 5, 2022 at 19:29
  • Okay I will run some tests with gzip disabled and report back, but that is a secondary to what I'm hoping someone knows re: file types and ETag behavior... to confirm, this server does have gzip enabled in the nginx.conf. Commented Sep 5, 2022 at 20:01
  • I'm reporting back that disabling gzip in Nginx, and then disabling Cloudflare (which adds gzip to text/html content) did indeed recover my missing ETag headers for .html files I was testing on my server. In fact, even when I didn't set etag on; Nginx still decided to send an ETag header for my HTML files, so this does seem to be gzip related. Commented Sep 6, 2022 at 21:31

1 Answer 1

0

What I've discovered is that Nginx will strip the content-length header from certain file types such as my .html files if your server has gzip enabled. However, the etag header does seem to remain intact unless you are using Cloudflare, which strips etag headers from certain content.

To make matters more confusing, Cloudflare adds gzip to certain content even if Nginx has gzip disabled... for example, HTML or dynamic content, etc.

Now I'm still confused here, because my understanding is that Nginx generates ETags based on the content-length and last-modified headers, so I don't know how the etag header can remain on e.g. .html or .js or .css files that are being gzipped already by Nginx, because content-length is already stripped by Nginx in such cases due to gzip being enabled...

According to one dude, using static gzip instead can solve the content-length dilemna, but that's another challenge for those not interested in using static gzip.

But back to the primary question, what file types does Nginx generate Etags for by default?... well, I'm still not sure the answer to this question but I'm guessing maybe Nginx will generate ETags for any file on disk that has a last-modified timestamp and a static content-length value... even if Nginx strips out content-length because of gzip. Yah, I don't get it either.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .