nginx自1.21.6起废弃http2_max_field_size,因http/2的hpack压缩在协议层完成,nginx解析仍基于未压缩文本,故统一使用client_header_buffer_size和large_client_header_buffers控制请求头大小。

在 HTTP/2 场景下,请求头体积显著增大(比如长 Cookie、多级网关注入 Header、JWT Token 等),容易触发 400 或 494 错误。但要注意:http2_max_field_size 已被弃用,Nginx 官方明确提示应改用 large_client_header_buffers 配合 client_header_buffer_size 来统一控制请求头大小限制。
为什么 http2_max_field_size 不再推荐使用
从 Nginx 1.21.6 起,http2_max_field_size 和 http2_max_header_size 指令已被标记为 obsolete(废弃)。官方日志会输出警告:
这是因为 HTTP/2 的 HPACK 压缩发生在协议层,而 Nginx 实际解析请求头时,仍基于原始的文本格式(未压缩前)做缓冲区分配。所以真正起作用的是通用请求头缓冲配置,而非仅限于 HTTP/2 的专用指令。
替代方案:用 client_header_buffer_size + large_client_header_buffers 控制字段与整体大小
这两个指令共同决定 Nginx 能接受多大的请求头(含请求行 + 所有 Header 字段):
- client_header_buffer_size:默认 1k,用于存放“常规大小”的请求头;若请求头未超此值,直接使用该缓冲区
-
large_client_header_buffers:格式为
large_client_header_buffers number size,例如large_client_header_buffers 4 8k表示最多分配 4 个 8k 缓冲区,即总上限为 32k - 单个 Header 字段(如
Cookie: xxxxx...)不能超过size值(即 8k),否则返回 400(实际是 494) - 整个请求头(含请求行)不能超过
number × size,超出则返回 414(Request-URI Too Large)
典型调优建议(适用于 JWT、微服务网关等场景)
当应用依赖超长 Cookie(>4k)、携带多层认证 Header 或动态生成大 Header 时,可按如下方式调整:
- 将
client_header_buffer_size设为2k或4k,减少小请求的内存开销 - 设置
large_client_header_buffers 4 8k,允许单字段最大 8k,整体请求头上限 32k - 配合日志字段
$request_length监控真实请求头大小,便于定位问题 - 避免盲目设成
large_client_header_buffers 1 64k—— 这样单字段上限仍是 64k,但失去分块管理能力,且易被恶意构造攻击
验证是否生效的小技巧
用 curl 构造边界测试请求:
- 测试单字段超限:curl -H "X-Long-Header: $(printf 'a%.0s' {1..8193})" http://your.site/ → 应返回 400
- 测试整体超限:curl -v "http://your.site/?$(printf 'a%.0s' {1..32769})" → 应返回 414
- 检查 access.log 中
$request_length字段,确认常见请求是否落在安全区间内











