何が起きたのか?
409 は「サーバーの今の状態と、送られてきたリクエストの前提が食い違っている」というサインです。 教室で言えば、二人の生徒が同じ瞬間に黒板の同じ場所へ別の答えを書こうとしてチョークがぶつかった——そんな状況に近いかもしれません。
リクエスト自体は文法も意味も正しい。ただ、「自分が見ていた古い状態」を前提に書こうとしたら、別の誰かがすでに書き換えていた。サーバーは「今の黒板はあなたが見ていた頃と違いますよ」と教えてくれているだけです。
黒板からのひとこと
授業中、班で一枚のノートに記録を書き込むとします。誰かが消しかけている横で別の子が書き始めたら、結果はぐちゃぐちゃになる。だから順番を整える仕組みが要ります。Web では ETag や If-Match といったヘッダがその役割を担います。
409 が返ってくるのは、サーバーがその仕組みをきちんと働かせている証拠でもあります。データを上書きで壊すより、いったん止めて「最新を見てから書き直してね」と返す。そのほうが、結果的に安全です。
解決への歩み
大丈夫、次はこうしてみよう:
- 最新の状態を取り直す:GET でリソースを再取得し、新しい ETag やバージョンを得る
- 差分を確認してから再送:他者の変更を上書きしていないか、変更点をマージする
- 一意制約のキーを変える:作成時の衝突なら、メールやスラッグの重複を解消
- 競合検知の方針を確認(管理者向け):楽観ロックの ETag、悲観ロックの利用範囲、リトライポリシーを見直す
実際にはこう見える
$ リクエスト
curl -i https://example.com/some/path ↓ レスポンス
HTTP/1.1 409 Conflict
Content-Type: text/html; charset=utf-8
<!DOCTYPE html>
<html><body><h1>409 Conflict</h1></body></html>