devkult_
tools29converters34

ETag

response headercaching

An identifier for a specific version of a resource, used to revalidate cached copies and to prevent lost updates.

An ETag (entity tag) is an opaque string the server attaches to a response — often a hash of the content. Clients send it back in If-None-Match to ask 'has this changed?' (a 304 means no), or in If-Match to say 'only apply my update if this is still the version I saw'.

Syntax

ETag: "<value>"   or   ETag: W/"<value>"

Defined in RFC 9110 §8.8.3 — ETag.

Values

"<value>"strong ETag: byte-for-byte identical content
W/"<value>"weak ETag: equivalent content, not necessarily identical bytes

Examples

ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"

a strong ETag built from a content hash

ETag: W/"0815"

a weak ETag

Good to know

  • The quotes are part of the value.
  • When several servers serve the same files, build ETags from the content, not from inode numbers or timestamps — otherwise each server reports a different ETag and revalidation keeps missing.
  • Compression middleware often turns strong ETags weak, because compressing changes the bytes.

Further reading: HTTP caching explained

Who sets ETag

Most servers generate ETags for you: Express adds weak ETags to res.send() responses, Next.js to pages (the generateEtags option), and nginx to static files (etag on; by default). Check one with curl -sI https://example.com/ | grep -i etag, then send it back with -H 'If-None-Match: "…"' to see the 304.

Check it

Fetch only the response headers and filter for ETag. In the browser, it's under Response Headers in DevTools → Network.

curl -sI https://example.com/ | grep -i '^etag:'

To compare response headers across many URLs at once, use the HTTP Status Checker.

Frequently asked questions

Is an ETag required for a 304?

A validator is — ETag or Last-Modified. ETag is more precise, since Last-Modified only has one-second resolution.

Can ETags be used for tracking?

They can: a unique ETag per visitor behaves like a cookie. That's one reason browsers now partition their caches by site.

Status codes it appears with
Related headers