Technology that earns its place.

An If-Match Header Can Stop an Update From Overwriting Someone Else’s Change

A developer's desk with code visible on a monitor.
AI-generated photographic illustration; not documentary photography.

Two editors load the same record. The first saves a correction; the second saves an older version a moment later. Without a concurrency check, the second write may erase the first change even though both requests appeared successful.

MDN’s conditional-request guide describes using validators to prevent this lost-update problem. A client can send the version’s ETag in an If-Match header. If the precondition is not satisfied, the server can reject the write with 412 Precondition Failed.

A small sequence to test

  1. Read a resource and retain the ETag supplied with that representation.
  2. Submit the edit with the matching precondition required by the API.
  3. Have the server evaluate the condition atomically with the update.
  4. If it fails, retrieve the current state and let the user resolve the difference.

The atomic step matters. Checking a version, then updating later without protection, leaves room for another write between the two operations. The storage and application layers need to preserve the intended guarantee.

Do not respond to a 412 by automatically retrying the same stale body without the condition. That bypasses the protection. Show the user what changed or provide a deliberate merge workflow appropriate to the data.

Make the conflict test meaningful

In a test environment, open the same version in two clients. Save different edits from each and verify that the stale write is rejected while the accepted change remains. Also test the API’s documented behaviour when the precondition is missing.

Authentication and authorisation remain separate requirements. An ETag is a version validator, not permission to edit the resource. Avoid including secrets in error responses, and keep the conflict message useful without exposing another user’s private information.

A successful implementation makes a conflict visible at the point it can still be resolved, instead of discovering the lost work after both users have moved on.