409 Conflict

Client Error - Request conflicts with current resource state

HTTP 409 Conflict

What It Means

The HTTP 409 Conflict status code indicates that the request could not be completed due to a conflict with the current state of the target resource. This is often resolvable by the user.

Common Scenarios

  • Duplicate entry: Creating a user with an email that already exists
  • Edit conflict: Two users editing the same document simultaneously
  • Version mismatch: Optimistic locking detected stale data
  • State conflict: Trying to publish an already-published post
  • Delete conflict: Resource has dependent records

Example Responses

Duplicate email

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

{
  "error": "Conflict",
  "message": "A user with this email already exists",
  "field": "email"
}

Edit conflict (optimistic locking)

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

{
  "error": "Conflict",
  "message": "Document was modified by another user",
  "your_version": 3,
  "current_version": 5
}

Optimistic Locking

Optimistic locking prevents lost updates by checking a version number before saving:

  1. Client fetches record with version=5
  2. Client edits and sends update with version=5
  3. Server checks: current version is now 6 (someone else edited)
  4. Server returns 409 Conflict

Implementation

Express.js - Duplicate check

app.post('/api/users', async (req, res) => {
  const existing = await User.findOne({ email: req.body.email });
  if (existing) {
    return res.status(409).json({
      error: 'Conflict',
      message: 'Email already registered',
      field: 'email'
    });
  }
  // Create user...
});

Optimistic locking with version

app.put('/api/documents/:id', async (req, res) => {
  const { version, content } = req.body;

  const result = await db.query(
    `UPDATE documents
     SET content = ?, version = version + 1
     WHERE id = ? AND version = ?`,
    [content, req.params.id, version]
  );

  if (result.affectedRows === 0) {
    return res.status(409).json({
      error: 'Conflict',
      message: 'Document was modified'
    });
  }

  res.json({ success: true });
});

409 vs Other Codes

Code Use When
409 State conflict (duplicate, version mismatch)
400 Invalid request format/syntax
422 Valid format but semantic errors

Best Practices

  • Include details about what caused the conflict
  • For edit conflicts, include both versions for merging
  • Suggest resolution steps in the error message
  • Use appropriate response body with conflict details

Frequently Asked Questions

What does HTTP 409 Conflict mean?
HTTP 409 Conflict means the request could not be completed because it conflicts with the current state of the target resource. Common examples include trying to create a user with an email that already exists, or updating a resource that was modified by someone else since you last read it.
When should I use 409 instead of 400?
Use 409 Conflict when the request is valid but conflicts with the current state of the resource (like duplicate entries or version mismatches). Use 400 Bad Request when the request syntax is invalid or malformed. Use 422 Unprocessable Entity when the request format is valid but contains semantic errors like validation failures.
What is optimistic locking and how does it relate to 409?
Optimistic locking is a concurrency control strategy where you check a version number before saving changes. If the version has changed since you read the data, another user modified it, and the server returns 409 Conflict. This prevents lost updates without locking the resource during editing.
How should I handle a 409 Conflict in my client code?
For duplicate entries, show the user a message that the resource already exists and suggest alternatives. For edit conflicts, fetch the latest version and either auto-merge the changes or show both versions to the user for manual resolution. Always read the response body for conflict details.
Should the 409 response include details about the conflict?
Yes. The response body should include enough information for the client to resolve the conflict. Include the conflicting field name, the current state of the resource, or version numbers. This helps both developers debugging and client applications implementing automatic conflict resolution.

Monitor your API health

Track conflict errors and data integrity issues.

Start monitoring free →

Related Status Codes

More Resources