flashman
← All guides

HTTP conditional writes and 412 responses

Prevent lost updates with strong ETags, If-Match, atomic precondition evaluation, representation-aware validators, explicit conflict UX, proxy controls, and tests.

2026-09-28 · 8 min read

  • http
  • concurrency
  • api

Conditional requests let a client attach assumptions about resource state to an HTTP operation. For updates and deletes, If-Match with a strong entity tag is a common way to reject stale writes before they overwrite newer work.

When the selected representation no longer matches, the server returns 412 Precondition Failed. The response is not an invitation to retry blindly; it tells the client to refresh or reconcile its intent.

Define the concurrency contract

Decide which resources require lost-update protection, which retrieval returns their validator, and which modifying methods require If-Match. Document behavior for a missing precondition separately from behavior for a supplied but false one.

  • Return validators on authoritative reads.
  • Require preconditions consistently across write paths.
  • Use explicit policy for create-if-absent operations.
  • Keep authorization independent from validator secrecy.

Generate strong representation validators

A strong ETag must change whenever the selected representation changes in a way relevant to byte-for-byte comparison. It may derive from a version, revision identity, or canonical representation, but clients should treat it as opaque.

Account for content negotiation, field visibility, compression layers, and per-user representations. Do not expose a cross-tenant oracle or assume a client-side hash of pretty-printed JSON reproduces a server validator.

Evaluate the condition atomically

The server must compare the precondition and perform the mutation as one concurrency-controlled operation. A read-then-write sequence without a lock, compare-and-swap predicate, or equivalent transaction can pass two competing writers.

If-Match uses strong comparison. Define wildcard handling, missing-resource behavior, and interactions with other preconditions according to HTTP semantics before mapping the operation into database conditions.

Give clients a reconciliation path

On 412, provide a safe problem representation or documentation link that tells the client to retrieve current state. Interactive clients can show a structured diff or reapply a user-confirmed edit; automated clients need domain-specific merge or abandonment rules.

Never replace the stale validator with the latest one and silently resubmit the same mutation. That converts an intentional concurrency check into last-write-wins behavior.

Test variants and competing writers

Use Flashman's URL parser for identifiers, hash tool for public representation fixtures, timestamp converter for date conditions, diff for reconciliation, and JSON formatter for problem responses.

Cover current and stale tags, weak tags, wildcard conditions, missing resources, simultaneous updates and deletes, negotiated variants, authorization changes, proxy transformations, date precision, atomicity failures, retries, caches, and representation migrations.

Try these tools