concept Delivery & performance
ETag and conditional requests
An HTTP ETag is an opaque representation validator.
What it means
An ETag is a validator for a selected representation of a resource. Clients can use it to ask whether a stored response is still current or to guard a write against unintended overwrites. If-None-Match and If-Match have different preconditions and comparison rules; the same tag does not imply identical HTTP outcomes for GET and PUT. HTTP conditionals
Try it
Simulation — compare validators. Set the stored client tag and current resource tag to "v1" and request GET with If-None-Match: the result is 304 without response content. Change the current tag to "v2" for a full 200 representation. Switch to PUT with If-Match and try the weak W/"v1": it fails a strong check. Run a matching strong guarded write and inspect the new virtual validator; a later stale write should fail. Reset discards the virtual update.
ETag preconditions
Compare validators for GET revalidation or a guarded PUT; view response and virtual representation state.
Weak comparison matched: a 304 supplies no representation body.
| Observation | Model value |
|---|---|
| Method | GET |
| Condition | If-None-Match |
| Client | "v1" |
| Current before first request | "v1" |
| Strong comparison? | false |
| Match now? | true |
| Response | 304 |
| Response body? | None |
| Stored validator after step | "v1" |
| Virtual stage | Initial request preview |
Local, bounded educational fixture. No DNS, mail, certificate, network, socket or external request is performed.
About this model
ETags are opaque validators, not necessarily hashes. If-None-Match uses weak comparison; If-Match uses strong comparison. No actual HTTP or persisted writes occur.
See the article’s protocol sources and model limits. The scene does not alter a real system.
How the mechanism works
A server chooses opaque entity-tag values. Clients must not assume an ETag is always a file hash, timestamp or portable identifier for a resource across representations. Weak tags allow semantically equivalent representations under the relevant comparison; strong comparison demands matching opaque tags without weakness. The same literal-looking tag can produce different conditional behavior depending on the header and method.
On a matching If-None-Match GET, the server can send 304 and selected representation metadata; the client uses a previously stored body according to cache rules. For a conditional PUT, a failing If-Match protects against overwriting a changed version and normally produces 412. An accepted update can change the ETag; repeating the previous strong precondition then becomes stale. The exercise distinguishes the status of a response from the state of its virtual representation.
A stale editor attempts a conditional PUT
An editor retrieves version "v1" and saves it with If-Match: "v1". In this synthetic resource, the strong match permits the first conditional PUT and advances the stored validator to "v3". Replay the old If-Match: "v1" and it now fails with 412 Precondition Failed. The example changes only local model state; it performs no HTTP write.
Contrast that with If-None-Match: "v1" on GET when current content is still tagged "v1": a weak comparison can yield 304 Not Modified and the client reuses its already held representation. A W/ prefix matters for strong comparison. Do not assume a real API supports these operations unless its contract says so.
A weak validator is useful for retrieval, not a write lock
Suppose the current selected representation has weak ETag W/"v1". For a conditional GET with If-None-Match: W/"v1", the weak comparison can match and permit a 304 Not Modified response under the applicable rules. The same weak tag in If-Match on a state-changing request does not satisfy the strong comparison used to protect a write. A client must not assume that successful cache validation implies protection against overwriting concurrent work.
The fixture demonstrates only the selected validator comparisons and local resource revisions. Real services might omit ETags, generate them from different representations or impose additional write preconditions. On a 412, STOP and fetch the current state to resolve the conflict instead of blindly resubmitting the old body. Conditional requests
In practice
Record the exact selected representation, method, validator and precondition sent on the wire. For an authorized edit, read current state and use appropriate conditional writes; after 412, inspect the new state instead of blindly retrying the old payload. An ETag need not be a cryptographic hash and should not be treated as an integrity or authentication signature.
Limits and common mistakes
This model allows just GET, HEAD and PUT with If-None-Match/If-Match and a few fixed ETags. It does not cover wildcard conditions, full precondition precedence, partial representations, all response headers or actual persistence. Its write is local to memory only.
Key takeaways
Cache validators and concurrency guards serve different purposes. Select the correct precondition for the intended method, and respect a 412 as evidence that the previously observed state cannot be assumed current.
Frequently asked questions
Editorial questions, answered from the sources listed for this article.
Why did matching ETag produce 304 once and 412 another time?
The precondition and method differ. A matching If-None-Match on GET can produce 304; a failed strong If-Match guard on PUT produces 412.
Must an ETag be a hash of the file bytes?
No. It is an opaque validator chosen by the server under HTTP semantics, not necessarily a checksum.
Can a weak ETag validate a cached GET?
Yes. If-None-Match uses weak comparison for conditional cache validation under the relevant rules.
Can If-Match accept weak comparison for a protected PUT?
No. If-Match uses strong comparison, so a weak validator does not provide the same lost-update protection.
Sources & model boundaries
Primary references used for this explanation. The interactive example is an educational model, not a live check.
- HTTP Semantics
HTTP method, status (§15), redirection (§15.4) and validators/preconditions (§§8,13). Statuses, redirects/methods, conditional requests and validators.
Checked .
- HTTP Caching
Storage, cache freshness and revalidation (§§3–5). Cache directives, freshness, validation and shared/private restrictions.
Checked .
- MDN — ETag header
ETag, conditional retrieval and weak/strong validators. Opaque validators, conditional reads/updates; not a mandatory content-hash format.
Checked .