HTTP/2 下超大 Cookie 更容易出问题,因 HPACK 强制将所有 Cookie 合并为单个字段传输,而 http2_max_field_size 限制解压后单字段长度,默认 4KB 不足;HTTP/1.1 则拆分为多行,不受此限。

默认 4KB 的 http2_max_field_size 在含长 JWT、多级网关注入 Cookie 或调试头的场景下极易触发 431 错误或静默断连,必须显式调大。
为什么 HTTP/2 下超大 Cookie 更容易出问题
HTTP/2 使用 HPACK 压缩头部,http2_max_field_size 控制的是「单个 Header 字段解压后」的最大长度(不是总头大小),而 Cookie 通常被塞进一个 Cookie 字段里传输。现代应用中带长 JWT 的 Cookie 动辄 8–16KB,远超默认 4KB,HPACK 解码失败后 Nginx 会直接关闭流,浏览器可能只看到空白页或连接重置,error log 中常无明显报错,只有 "client sent too large field" 或连接中断记录。
- HTTP/1.1 下 Cookie 被拆成多个
Cookie: key=value行,不受单字段限制影响 - HTTP/2 强制将所有 Cookie 合并为一个
Cookie字段进行 HPACK 编码,字段长度即为全部 Cookie 内容字节数 - 该指令与
proxy_buffer_size无关——后者管后端响应头,http2_max_field_size管客户端请求头的字段解码
怎么设置 http2_max_field_size 才安全有效
它必须放在 http 或 server 块中,不能在 location 里;且仅对启用了 HTTP/2 的 server 生效(即 listen 行含 http2)。
- 先确认当前 Cookie 实际长度:用 Chrome DevTools → Application → Cookies 查看原始值,或
curl -v https://yoursite.com 2>&1 | grep Cookie抓请求头再wc -c - 起步建议设为
http2_max_field_size 16k;,若仍不稳定,逐步试32k或64k(不建议超过 64k,HPACK 效率会显著下降) - 必须同步检查
http2_max_header_size(默认 16KB),它控制整个请求头总长,应 ≥ 所有字段长度之和,推荐设为http2_max_header_size 128k; - 若使用宝塔等面板,修改位置在「网站配置文件」中带
listen 443 ssl http2;的server块顶部附近,改完务必nginx -t && nginx -s reload
常见误配与排查盲点
很多团队调大了 proxy_buffer_size 却没动 http2_max_field_size,结果 502 消失了但 431 还在,因为这是两个完全独立的缓冲边界。
- 错误现象:浏览器返回
431 Request Header Fields Too Large,或无响应、连接被 RST,Nginx error log 出现"client sent too large field" - 混淆点:
client_header_buffer_size和large_client_header_buffers是 HTTP/1.x 用的,对 HTTP/2 请求头无效,改了也没用 - 验证是否生效:用
curl -v --http2 -H "Cookie: $(python3 -c 'print(\"a\"*20000)')" https://yoursite.com模拟大 Cookie 请求,观察是否返回 431 - 别忘了后端:即使 Nginx 接收成功,后端框架(如 Spring Boot、Express)也可能有自己的 header 大小限制,需一并检查
真正难处理的不是调参本身,而是当多个网关层层注入 X-Trace-ID、X-Forwarded-For、Authorization 和 Cookie 后,Header 总长和单字段长度都逼近临界值——这时得靠抓包看原始帧,而不是只信浏览器开发者工具里显示的“已格式化”头信息。











