The journal
What is an ETag response header?
A concise, practical explanation of the HTTP ETag response header, how it works with If-None-Match and If-Match, and when to use weak vs strong validators, with clear examples and a setup checklist.

An ETag (entity tag) is an HTTP response header that identifies a specific version of a resource so clients and caches can detect changes efficiently and avoid downloading the body when it hasn’t changed. It is also used for optimistic concurrency control to prevent overwriting concurrent updates MDN ETag.
What an ETag does
Servers attach an ETag to a representation of a resource; if the resource changes, the server must generate a new ETag. Clients can compare ETags to determine whether two representations are the same. This enables two important behaviors:
- Efficient caching: a client sends If-None-Match with a stored ETag; if it matches the current ETag, the server returns 304 Not Modified without a body MDN ETag.
- Optimistic concurrency: a client sends If-Match with the last-seen ETag when updating; if it doesn’t match, the server should reject with 412 Precondition Failed MDN ETag.
ETag is both a response header and a representation header, describing the entity returned in the message MDN response header glossary.

Syntax and validator types
ETag: "<etag_value>"
ETag: W/"<etag_value>"
- Strong ETag: "<value>" compares byte-for-byte. Best for precise comparisons and compatible with caching of byte range requests.
- Weak ETag: W/"<value>" compares semantically (not byte-identical). Easier to generate, but weak validators are less useful for comparisons and prevent caching when byte range requests are used MDN ETag.
How conditional requests work with ETags
Revalidate cached content (If-None-Match → 304)
# First response
HTTP/1.1 200 OK
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"
Content-Type: application/json
{"data":"..."}
# Later request revalidating the cache
GET /resource HTTP/1.1
If-None-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4"
# If unchanged
HTTP/1.1 304 Not Modified
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"
When the client’s ETag matches the server’s current ETag, the server replies with 304 and no body, signaling the cached copy is still fresh to use MDN ETag. For more on the status itself, see our explainer: What does HTTP code 304 mean?
Prevent overwrites (If-Match → 412)
# Client fetched the resource earlier and kept the ETag
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"
# Client attempts an update only if it still matches
PUT /resource HTTP/1.1
If-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4"
Content-Type: application/json
{"data":"new"}
# If someone else changed it in the meantime
HTTP/1.1 412 Precondition Failed
If the ETag no longer matches, the server rejects the update to avoid a mid-air collision MDN ETag. If you’re seeing 412s in your workflow, try our guide: How to fix 412 Precondition Failed.
Generating ETags
The HTTP specification does not mandate how to generate ETags. Common approaches include a hash of the response body, a hash of last-modified data, or a revision/version number. Whatever you choose, regenerate the ETag whenever the resource changes MDN ETag.
ETag, Last-Modified and cache freshness
- ETag vs Last-Modified: Last-Modified is easier to compute but less accurate than ETag for comparing versions. Both can be used for conditional requests MDN headers.
- Freshness vs validation: Cache freshness lifetimes are communicated with Cache-Control or Expires; ETags participate in revalidation (If-None-Match / If-Match) rather than declaring freshness MDN headers.

Put this into practice
Keep the stored representation and its ETag together in a small test. Check an unchanged response and a changed response, rather than treating the presence of a header as proof that caching or concurrency protection works.
Implement ETags safely and effectively
FAQ
Should I use strong or weak ETags?
Use strong ETags when you need byte-for-byte comparisons or range-request caching. Weak ETags are easier to compute but are less useful for comparisons and prevent caching with byte range requests MDN ETag.
Are ETag values meaningful?
No. ETag values are opaque strings defined by the server. Common implementations use hashes or revision IDs, but the generation method is not specified by HTTP MDN ETag.