Developer Toolbox
4xx client errorRetry after resolvingOften paired with ETag

409 Conflict

The request can't be applied because it conflicts with the current state of the resource. The client is expected to be able to resolve the conflict and send the request again, so a useful 409 says what the conflict is.

Open Diff Viewer Compare your version with the server's.

Common causes

  • Creating something that must be unique and already exists, such as a username or a slug.
  • A retry with the same idempotency key while the first request is still being processed.
  • Two clients edited the same record, and the second write would silently overwrite the first.
  • A change the current state doesn't allow, such as cancelling an order that has already shipped.
  • In Git hosting APIs, updating a file with a stale sha, or merging a branch that has conflicts.

How to fix it

  • Fetch the current version, show the difference, and let the user or your code merge before sending again.
  • Detect lost updates on purpose: send If-Match with the ETag you read, and the server answers 412 when someone else wrote first.
  • For create requests, decide what a duplicate means. Returning the existing resource with 200 is often friendlier than a 409.
  • Don't retry a 409 automatically with the same body: a conflict over the data will only repeat. The exception is a request still in progress under the same idempotency key, which a retry after a short wait resolves.

409 or 412?

412 Precondition Failed answers a conditional request (If-Match) whose check failed. 409 is for conflicts the client didn't ask the server to check: a duplicate key, a forbidden state change.

409 or 422?

422 means the data is invalid on its own terms. 409 means the data is fine, but doesn't fit what is already stored.

Example

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

{
  "title": "Version conflict",
  "status": 409,
  "detail": "The document was changed by another user at 10:42.",
  "currentVersion": 7
}

Defined in RFC 9110, section 15.5.10.