首页/网络/协议速查/412 Precondition Failed 前置条件失败
HTTP 方法与状态码91 条

412 Precondition Failed 前置条件失败

请求中的条件头(If-Match、If-Unmodified-Since 等)不成立,服务器拒绝执行。

协议速查网络更新于 2026-10-13

前置条件失败的含义

412 Precondition Failed 表示请求里的条件头不成立,服务器因此拒绝执行。最常见的场景是乐观并发控制:客户端带上 If-Match 与自己看到的 ETag,如果资源已经被别人改过(当前 ETag 不匹配),服务器就回 412 而不是默默覆盖。理解 412 的关键是它一定由客户端主动发出的条件头触发,而不是服务器单方面的判断。

基本信息

名称412 Precondition Failed
语义条件请求中的前置条件未满足
规范RFC 9110 §15.5.13,条件请求见 RFC 9110 §13
常见条件头If-Match、If-None-Match、If-Unmodified-Since、If-Modified-Since
重试特性请求本身是幂等的,客户端可重新拉取最新版本后重放

条件头对应的结果

条件头条件不满足时典型用途
If-Match412防止覆盖他人修改(乐观锁)
If-None-Match对应 304 或 412避免重复创建、配合缓存校验
If-Unmodified-Since412按时间做写入保护
If-Modified-Since返回 304 或正常响应条件 GET 节省带宽

乐观锁更新

乐观锁更新
curl -si -X PUT https://api.example.com/docs/7 \
  -H 'If-Match: "v5"' -H 'Content-Type: text/markdown' -d @doc.md
# 若当前 ETag 是 "v6" → HTTP/1.1 412 Precondition Failed
# 正确处理:重新 GET 拿到最新内容与 ETag,合并后再带新的 If-Match 重试
curl -si https://api.example.com/docs/7 | grep -i etag

典型使用场景

  • 多人协作编辑文档,避免后写覆盖先写
  • 配置中心下发配置时校验版本,防止并发覆盖
  • 文件上传与对象存储的条件写入,保证只对预期版本操作
  • 接口层拒绝「无版本号更新」,用 428 要求先带上条件头
412 与 409 的边界:412 由条件头触发,语义清晰且可自动重试;409 表示资源状态冲突(如唯一键重复、状态机不允许),通常需要业务判断。实现时不要混用,否则调用方的重试策略会失准。
返回 412 时应同时在响应体里给出当前版本或最新 ETag,客户端才能一次性完成「拉新、合并、重试」,否则会出现反复 412 的请求风暴。
注意弱验证器:带 W/ 前缀的弱 ETag 只保证语义等价而不保证字节一致,用于 If-Match 做写入保护时需服务端明确支持,否则应改用强验证器或版本号字段。

易错点

  • 用 If-Modified-Since 做写入保护:它只适用于 GET 与 HEAD,用在写请求上会被忽略,保护形同虚设
  • ETag 由负载均衡后不同节点各自生成:同一资源在两台机器上算出不同 ETag,客户端永远拿到 412,应统一算法或使用共享存储版本号
  • 收到 412 后原样重试:条件不变结果必然还是 412,正确做法是先拉取最新版本再重放
  • 返回 412 却不带当前版本信息:客户端只能猜测,容易出现重试风暴与用户体验劣化

数据来源与参考

  • RFC 9110 §15.5.13 412
  • RFC 9110 §13 条件请求

相关工具

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌