MockFoxAdvertise

HTTP 409 Conflict

Updated Free mock REST & WebSocket APIs

HTTP 409 Conflict — The request conflicts with the current state of the resource.

Class
4xx Client Error
Defined in
RFC 9110 §15.5.10
Official
Yes (IANA registry)
Cacheable by default
No (unless Cache-Control/Expires say so)
Safe to retry
Not without changing the request

Try it: get a real 409 response

Our test endpoint answers every request with 409 Conflict.

curl -i https://mockfox.dev/api/status/409

Use it in tests, health-check monitors or to see how your client handles a 409. Add ?delay=2000 to slow it down.

What does HTTP 409 mean?

409 Conflict means the request couldn't be completed because it conflicts with the current state of the target resource. The client can usually resolve the conflict and resubmit, so the response body should explain what conflicted.

When is 409 used?

  • Creating something that must be unique and already exists (a username or email already registered).
  • Concurrent edits: saving changes based on an outdated version of a document.
  • A state transition that isn't allowed (cancelling an order that has already shipped).
  • Git hosting and package registries rejecting a push or publish of an existing version.

Common causes of a 409

  • Someone (or another tab/device) changed the resource since you loaded it.
  • A duplicate submission — e.g. double-clicking a submit button.
  • A unique constraint in the database.

How to fix 409 Conflict

If you're visiting the site

  1. Refresh the page to load the latest version, then make your change again.
  2. If signing up, the email or username may already be in use — try logging in or resetting your password.

If you run the site or API (developers)

  1. Return a body that names the conflict, e.g. {"error":"email_taken"} or the current version.
  2. For lost-update protection use ETags with If-Match, answering 412 when they don't match (409 is fine for domain conflicts).
  3. Map database unique-constraint violations to 409 instead of letting them bubble up as 500.
  4. Use idempotency keys so retried requests don't produce spurious conflicts.

Returning or handling 409: server examples

Express

app.post("/api/users", async (req, res) => {
  try {
    res.status(201).json(await db.users.create(req.body));
  } catch (e) {
    if (e.code === "23505") // Postgres unique_violation
      return res.status(409).json({ error: "email_taken" });
    throw e;
  }
});

Next.js

// app/api/example/route.ts (Next.js App Router)
export async function PATCH(req: Request) {
  const { version, ...changes } = await req.json();
  const doc = await getDoc();
  if (doc.version !== version)
    return Response.json({ error: "conflict", current: doc }, { status: 409 });
  return Response.json(await saveDoc(changes));
}

Example 409 response

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

{"error":"email_taken","message":"An account with this email already exists."}

Related status codes

Related tools

Frequently asked questions

409 or 400 for a duplicate?

409 is the better fit: the request itself is valid, but it conflicts with existing data. 400 suggests the request is malformed.

409 or 422?

Use 422 when the input is invalid in itself (an email that's not an email). Use 409 when valid input clashes with the current state (an email that's already taken).

409 or 412?

412 Precondition Failed is specifically for failed conditional headers (If-Match, If-Unmodified-Since). 409 covers other state conflicts.