412 Precondition Failed는 요청 헤더에 담긴 전제 조건(If-Match, If-Unmodified-Since 등)이 서버에서 거짓으로 평가되어 요청을 수행하지 않았음을 뜻합니다. 주로 낙관적 동시성 제어(optimistic concurrency)에서 다른 사람이 먼저 리소스를 수정한 경우 발생합니다.
클라이언트가 이전에 받은 ETag를 If-Match로 보냈는데 그 사이 리소스가 바뀌어 현재 ETag와 달라지면, 서버는 덮어쓰기를 막기 위해 412를 반환합니다. 이는 '잃어버린 갱신(lost update)' 문제를 예방합니다.
PUT /docs/42 HTTP/1.1
Host: api.example.com
If-Match: "a1b2c3"
Content-Type: application/json
{"title":"Updated"}HTTP/1.1 412 Precondition Failed
Content-Type: application/json
{"error":"etag_mismatch","current":"\"z9y8x7\""}app.put('/docs/:id', (req, res) => {
const doc = db.get(req.params.id);
if (req.headers['if-match'] !== doc.etag) {
return res.status(412).json({ error: 'etag_mismatch', current: doc.etag });
}
db.update(req.params.id, req.body);
res.json({ ok: true });
});curl -X PUT https://api.example.com/docs/42 \
-H 'If-Match: "a1b2c3"' \
-H 'Content-Type: application/json' \
-d '{"title":"Updated"}'