sfw/fix
412 medium

412 Precondition Failed

You sent a conditional header but it no longer matches, the resource changed under you between read and write.

What you see

412 Precondition Failed

{
  "error": "precondition_failed",
  "detail": "The If-Match ETag does not match the current resource version."
}

What’s actually happening

You did everything right, GET the resource, grabbed the ETag, sent it back on If-Match, and the write still fails, this time with 412 instead of 428. The difference matters: 428 means you sent no condition; 412 means you sent one and it's stale. Someone (or another tab, or a background job) modified the record after your read, so the ETag you're holding describes a version that no longer exists. The server is protecting that other write by refusing yours.

Common causes

  • Genuine concurrent edit: another client wrote to the same resource between your GET and your PUT, bumping the ETag.
  • You're holding a cached or hardcoded ETag from an earlier session that's long out of date.
  • A weak vs strong ETag mismatch, the server changed how it computes the validator (e.g. after a deploy) and your stored value no longer compares equal.
  • If-Unmodified-Since with a date that's now earlier than the resource's real Last-Modified because it was touched.
  • A proxy or CDN rewriting/normalizing the ETag so the value you send back never matches the origin's.

How to fix it

  1. Refetch the resource to get the current ETagGET it again. The fresh response carries the new ETag, the one that reflects the latest write. Your old value is dead; don't reuse it.
  2. Show the user the conflict before retryingA blind retry with the new ETag will overwrite whatever the other writer just saved, reintroducing the lost-update bug 412 exists to stop. Diff the fresh server copy against the user's pending edit and let them merge or confirm.
  3. Resend the write with the up-to-date validatorOnce you (or the user) have reconciled, PUT/PATCH again with If-Match set to the new ETag. It now matches and the write goes through.
  4. Check for ETag rewriting in the pathcurl the origin directly and compare its ETag to what your client sees through the CDN/proxy. If they differ, the edge is mangling the header, configure it to pass ETags through untouched.
  5. Verify the validator format after deploysIf 412s spike right after a release, your server likely changed ETag generation. Invalidate client-side cached ETags so everyone refetches clean values.

Stop it recurring

On a 412, always refetch and surface the conflict to the user rather than auto-retrying, which is exactly the overwrite the check is meant to block.

Related errors