ETag
An opaque version identifier for a resource, used for caching and for detecting concurrent writes.
An ETag identifies a specific version of a resource. A client can send it back in If-None-Match to ask "has this changed?", receiving 304 and no body when it has not. Sent in If-Match on a write, it becomes optimistic locking: the write applies only if the resource is still at that version, and returns 412 otherwise.
Full guide:
When an API returns 412 and when it returns 409
— A 412 means a precondition you sent failed: you supplied If-Match with a version and the resource has moved on. A 409 means the request conflicts with current state for a reason you did not test for. The practical difference is that 412 tells you exactly which check failed, while 409 requires reading the body to find out.
Key facts
- If-None-Match is for reading and returns 304 with no body when the resource is unchanged.
- If-Match is for writing and returns 412 Precondition Failed when the resource has moved on, which is how lost updates are prevented.
- ETags are opaque: clients must never parse them or infer ordering from them, only compare them for equality.
- A 412 means someone else wrote first — the correct response is to re-read, merge, and retry, never to force the write.
Frequently asked questions
ETag or Last-Modified?
ETags are more precise. Last-Modified has one-second resolution, so two changes in the same second are indistinguishable, and it cannot express a change that leaves the timestamp untouched.
What should I do on a 412?
Re-read the resource, merge your change into the current version, and retry with the new ETag. Retrying with the old one will fail again, and dropping the precondition discards whatever the other writer just did.
Machine-readable copy of this page:
/glossary/etag.md