417 是什么
417 Expectation Failed 表示服务器无法满足请求里 Expect 头声明的期望,最常见的就是 Expect: 100-continue 无法被处理(RFC 9110 §15.5.18)。链路中旧代理不理解 100-continue,或服务端本身不支持这种预检,都会导致大体积上传在开始阶段就被拒绝。
基本信息
| 名称 | 417 Expectation Failed |
|---|---|
| 类别 | 4xx |
| 规范 | RFC 9110 §15.5.18 |
| 常见触发 | Expect: 100-continue 不被链路支持 |
| 典型客户端 | curl 对大于 1024 字节的 POST 会默认添加该头 |
| 标准化的期望值 | 目前只有 100-continue |
典型使用场景
- 大文件上传报 417:临时去掉 Expect 头让上传立刻开始
- 代理链路排查:确认中间设备是否支持 100-continue
- 脚本化上传的稳定性:显式控制 Expect 行为而不依赖默认值
- 协议实现:正确处理 100 Continue 与 417 的对照关系
- 弱网优化:权衡「先探路」与「直接发送」的取舍
- 日志分析:统计 417 集中的接口与客户端版本
关闭期望与观察协商
关闭期望与观察协商
# curl 对大体积 POST 默认添加 Expect: 100-continue
# 关闭方式:清空该头,实体立刻开始发送
curl -si -X POST -H 'Expect:' https://api.example.com/upload --data-binary @file.bin
# 观察协商过程,确认到底是谁拒绝了期望
curl -v -X POST -H 'Expect: 100-continue' --data-binary @file.bin https://api.example.com/upload 2>&1 | grep -E 'Expect|HTTP/1.1'100-continue 交互
| 方向 | 报文 | 含义 |
|---|---|---|
| 客户端 | Expect: 100-continue | 先探路,暂不发送实体 |
| 服务器 | HTTP/1.1 100 Continue | 同意接收实体,客户端继续发送 |
| 服务器 | HTTP/1.1 417 | 不支持该期望,客户端应停止上传 |
| 服务器 | 直接返回 4xx 或 5xx | 拒绝请求,无需再发送实体 |
去掉 Expect 的代价是提前发送可能被拒的实体;弱网大文件场景要权衡「多传一轮探路」与「被拒后重传」的成本。
Expect 目前只有 100-continue 被标准化,其他期望值服务器应返回 417,因此出现 417 时先看请求头里到底写了什么。
部分负载均衡设备会吞掉 100 Continue,客户端一直等不到响应才继续发送,表现成「上传卡住」;设置等待超时并回退为直接发送能明显改善体验。
Expect 的等待应设超时而不是无限等待:多数客户端库都提供该参数,默认值往往偏保守,弱网下容易表现为上传启动很慢。
自研服务端若声明支持 100-continue,就应在读取实体前真正返回 100 Continue,否则客户端会一直停在等待状态。