HTTP 409 Conflict
Конфликт состояния: запрос корректен, но ресурс изменился так, что применить его прямо сейчас невозможно.
Что означает HTTP 409
HTTP 409 Conflict означает, что сервер понял запрос, но не может его применить, поскольку он противоречит текущему состоянию целевого ресурса. Классический пример — коллизия редактирования: два клиента загрузили один и тот же документ, оба сохраняют изменения, и второе сохранение молча перезаписало бы первое.
В отличие от 400, сам запрос корректно сформирован — повторная отправка без изменений может позже завершиться успехом. Тело ответа должно объяснять, что именно конфликтует, чтобы клиент (или пользователь) мог устранить проблему и повторить попытку.
Частые причины ошибок 409
- Коллизия редактирования: ресурс был изменён кем-то другим с момента последнего получения его клиентом (часто это видно по ETag / If-Match).
- Создание ресурса, который уже существует, — дублирующееся имя пользователя, email, slug или имя файла.
- Несовпадение версии при optimistic locking: переданный номер версии устарел.
- Удаление или перемещение ресурса, у которого есть зависимые объекты, которые сервер отказывается оставлять без родителя.
- Параллельные шаги workflow применяются в неверном порядке (например, подтверждение уже отменённого заказа).
Как исправить со стороны разработчика
- Прочитайте тело ответа — хороший API указывает конфликтующее поле или ожидаемую текущую версию.
- Заново получите ресурс, повторно примените изменение поверх актуального состояния и отправьте запрос снова.
- Используйте условные запросы (If-Match с ETag), чтобы конфликты надёжно обнаруживались, а не приводили к перезаписи данных.
- Для конфликтов при создании дубликатов заранее определите подход к идемпотентности: возвращайте существующий ресурс либо 409 со ссылкой на него.
Пример ответа
HTTP/1.1 409 Conflict
Content-Type: application/json
{"error":"conflict","message":"document was modified by another user","current_version":42}Частые вопросы
В чём разница между 409 и 400?
400 означает, что сам запрос некорректен или содержит ошибки. 409 означает, что запрос в порядке, но конфликтует с текущим состоянием ресурса — повторная попытка после устранения конфликта может завершиться успешно.
Когда API должен возвращать 409 вместо 422?
Используйте 422 для ошибок валидации внутри тела запроса и 409 для конфликтов с существующим состоянием на сервере, например дубликатов или устаревших версий.
Как ETag помогают избежать ошибок 409?
Клиент отправляет If-Match с последним увиденным ETag; сервер применяет изменение только если ресурс не изменился, иначе вместо перезаписи возвращает 409 (или 412).