{ }HttpStatus.com

409 Conflict

The request conflicts with the current state of the target resource, such as a concurrent edit or a duplicate unique value.

Defined in RFC 9110 §15.5.10

What 409 means

409 Conflict means the request could not be completed because it collides with the current state of the target resource, most often a concurrent modification, a duplicate unique value, or a state transition the resource doesn't currently allow. RFC 9110 ties this specifically to the resource's state rather than the request's syntax, so unlike 400, the request itself is perfectly valid; it's just incompatible with what the server holds right now.

The classic case is optimistic concurrency control: a client fetches a resource, another client or process modifies it, and the first client's subsequent PUT or PATCH carries an If-Match header referencing the now-stale ETag, which the server rejects with 409 rather than silently overwriting the newer data, a so-called lost update. Duplicate-key inserts, creating a user with an email address that already exists, are another common source, as are workflow state machines rejecting an action that no longer applies, such as canceling an order that has already shipped.

Good API design uses the 409 response body to describe exactly what conflicted, ideally including the current server-side state, so the client can decide whether to merge, overwrite, or abandon its change rather than guessing. Retrying the identical request unchanged will simply produce the same conflict again, which is what distinguishes 409 from transient errors like 503 that are worth retrying as-is.

Common causes

  • Another client updated the resource after this client fetched its current state, and the two changes collide.
  • A creation request violates a unique constraint, such as an email address or slug that already exists.
  • The resource's current state doesn't allow the requested transition, such as cancelling an already-completed order.
  • A conditional request's If-Match ETag no longer matches the resource's current version.
  • The client is working from a stale cached copy of the resource.

How to fix a 409

If you are the client (browser user or API caller)

  • Refetch the resource's current state and reapply the intended change before retrying.
  • Use ETag and If-Match headers to detect conflicts explicitly and merge changes rather than overwrite blindly.
  • Inspect the response body for the specific conflicting fields and resolve them before resubmitting.

If you run the server

  • Include the current resource state or version in the 409 response body so the client can reconcile.
  • Implement optimistic locking via ETags or a version field to catch lost updates before they happen.
  • Enforce uniqueness and valid state transitions at the data layer so conflicts are caught reliably and returned as 409 rather than a generic 500.

Example

PUT /documents/88 HTTP/1.1
Host: api.example.com
If-Match: "v3-a1b2c3"

{"title": "Updated title"}

HTTP/1.1 409 Conflict
Content-Type: application/json

{"error": "conflict", "current_version": "v4-d4e5f6", "message": "Document was modified since you last fetched it"}
An If-Match precondition catches a lost update by rejecting a write based on a stale ETag.

Try it live

Our free status responder returns a real HTTP 409 you can point tests, monitors or a browser at.

GET https://mcp.httpstatus.com/status/409

Related status codes

Tools for debugging this