HTTP 409 Conflict
状態の衝突です。リクエスト自体は有効ですが、リソースが変化したため、現時点では適用できません。
HTTP 409 の意味
HTTP 409 Conflict は、サーバーがリクエストを理解したものの、対象リソースの現在の状態と矛盾するため適用できないことを意味します。典型的な例は編集の衝突です。2 つのクライアントが同じドキュメントを読み込み、両方が保存すると、2 回目の保存が 1 回目を黙って上書きしてしまいます。
400 と異なり、リクエスト自体は正しい形式です — 変更せずに再送信すれば、後で成功することもあります。レスポンスボディには、クライアント(またはユーザー)が問題を解決して再試行できるよう、何が衝突しているかを記載すべきです。
409 エラーのよくある原因
- 編集の衝突: クライアントが最後に取得して以降、他の誰かがリソースを変更した場合です(多くの場合 ETag / If-Match で判明します)。
- 既に存在するリソースを作成しようとした場合 — ユーザー名、メールアドレス、スラッグ、ファイル名の重複です。
- optimistic locking におけるバージョンの不一致: 送信されたバージョン番号が古い場合です。
- 依存関係を持つリソースの削除や移動を、サーバーが孤立させることを拒否する場合です。
- 並行するワークフローのステップが順序どおりに適用されなかった場合(例: 既にキャンセルされた注文を承認しようとするなど)。
開発者としての対処法
- レスポンスボディを確認してください — 優れた API は、衝突しているフィールドや期待される現在のバージョンを明示します。
- リソースを再取得し、最新の状態の上に変更を再適用してから、再送信してください。
- 条件付きリクエスト(ETag を用いた If-Match)を使用し、データを上書きするのではなく、衝突を確実に検出してください。
- 重複作成による衝突では、事前に冪等性(idempotency)の方針を決めてください。既存のリソースを返すか、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 が 422 ではなく 409 を返すべきなのはどのような場合ですか?
ペイロード内のバリデーションエラーには 422 を、重複や古いバージョンなど既存のサーバー側の状態との衝突には 409 を使用してください。
ETag は 409 エラーの回避にどう役立ちますか?
クライアントは最後に取得した ETag を If-Match として送信します。サーバーはリソースが変更されていない場合のみ変更を適用し、そうでなければ上書きする代わりに 409(または 412)を返します。