Representative interview topic

Backend interview: When should an API return 409 Conflict versus 422 Unprocessable Content?

BackendMedium
Offer.cc Editorial TeamPublished Updated

Question

When should an API return 409 Conflict rather than 422 Unprocessable Content? Give examples for concurrent updates, duplicate resources, and field validation.

1. Prompt and scenario

An order API accepts JSON requests. A client may send syntactically valid data with invalid field relationships, update an order from an old version, or try to create a username that already exists. Define the 409 and 422 boundary so clients know whether to edit the request, reread the resource, or stop retrying.

2. What the interviewer is testing

  • Whether you separate unprocessable request semantics from a conflict with current resource state.
  • Whether you know that repeating an unchanged 422 request normally produces the same result.
  • Whether you connect concurrency control, idempotent retries, and an error contract.
  • Whether you can position neighboring 400 and 412 responses and keep the policy consistent.

3. Clarifying questions to ask

  1. Does the API use ETags, version numbers, or another optimistic concurrency mechanism?
  2. Is “name already exists” modeled as a field rule or as the current state of a collection?
  3. Can the client reread the resource and show a diff to the user?
  4. Does the team already standardize error codes, field paths, and retry behavior?

4. A 30-second answer framework

Classify the cause first. Return 422 when the server understands the media type and syntax but cannot process the request’s semantics. Return 409 when the understandable request conflicts with the target resource’s current state. Use 400 for an unparseable request and 412 for a failed conditional-request precondition when that is the precise contract. Finish with machine-readable codes, repair guidance, and version information.

5. Step-by-step solution

Step one: Define the 422 boundary

422 means the content type and syntax are understood, but the contained instructions cannot be processed. Examples include an end date before a start date, a disallowed enum value, or an invalid field combination. The failure is usually independent of who last changed the resource, so the client should modify the payload before sending it again.

Step two: Define the 409 boundary

409 means the request conflicts with the target resource’s current state. Typical cases are a stale version, canceling an order that has shipped, or creating a resource that collides with an existing unique resource. Include the current version, conflict type, and a practical next step when safe to do so.

Step three: Position neighboring codes

Use 400 for broken JSON or missing syntax needed to parse the request. A request with If-Match that fails its stated condition can use 412; this is more precise than calling every conditional failure a 409. Document the chosen policy so endpoints do not invent incompatible meanings.

Step four: Design retries and the error body

Do not automatically retry an unchanged 422 payload because it is expected to fail again. A 409 may be repairable: reread, merge, and retry when the conflict type permits it, but never loop blindly. Return a stable code, field path or resource identifier, current version, and repair guidance; keep credentials and other secrets out of the response and logs.

6. Model answer

I classify the failure as a payload-semantic problem or a resource-state race. Reversed date ranges, invalid enums, and impossible field combinations are 422. A server that understands the request but sees a shipped order, a stale version, or an existing unique resource can return 409. Malformed JSON is 400, and an unmet If-Match condition can be 412.

>

For 422, I return a stable business code and field path so the client edits the data. For 409, I return the conflict type and server version or state so the client can reread and choose to merge, abandon, or retry. Neither status should trigger unconditional retries; an idempotency key prevents duplicate execution but does not remove a concurrency conflict. I document one policy for all endpoints and monitor how each error is repaired.

7. Common mistakes

  • Returning 409 for every business validation failure, implying that rereading the resource will fix it.
  • Returning 422 for a version conflict and hiding the signal that state changed.
  • Adding unlimited automatic retries for either status and creating a request storm.
  • Returning only a human message without a stable code, field path, or repair direction.
  • Choosing one code for every “duplicate” without defining whether it is a payload rule or a resource-state conflict.

8. Follow-up questions and answers

Follow-up one: Should a duplicate username be 409 or 422?

If uniqueness is modeled as the current state of the collection, 409 communicates a state conflict. If the team models it as field-semantic validation, 422 can be consistent. Stable contracts and predictable client behavior matter more than a universal label.

Follow-up two: Is every 409 retryable?

No. A version conflict may be retried after merging, while canceling a shipped order should stop and show the current state. The response should communicate whether the conflict is repairable.

Follow-up three: Can 422 represent a permission failure?

It should not replace authentication and authorization semantics. Missing authentication is generally 401, and an authenticated caller without permission is generally 403. Reserve 422 for content whose semantics cannot be processed.

Public sources

Related questions