Nginx 报 414 是因 client_header_buffer_size 和 large_client_header_buffers 过小,proxy_buffer_size 无关URI长度;应调大前者(如 client_header_buffer_size 2k; large_client_header_buffers 4 16k),并用 curl 测试验证。

当 Nginx 作为反向代理时,如果客户端发起的请求 URL 过长(比如含超长 query string 或 base64 编码参数),后端服务可能正常,但 Nginx 自身会在转发前就报 414 Request-URI Too Large 或直接拒绝连接。这通常不是后端限制,而是 Nginx 的缓冲区默认值太小,proxy_buffer_size 并不控制 URI 长度 —— 真正起作用的是 large_client_header_buffers 和 client_header_buffer_size。但很多人误配 proxy_buffer_size,导致问题没解决还掩盖了根源。
明确:proxy_buffer_size 不管 URL 长度
proxy_buffer_size 只影响 Nginx 从上游(后端)读取响应头时的缓冲区大小,和客户端发来的请求头(包括 Request-URI)完全无关。它解决的是“后端返回的响应头太大,Nginx 没空间存”的问题,不是“用户 URL 太长”的问题。
- 典型场景:后端返回含大量 Set-Cookie、自定义 header 或超长 Location 的响应,Nginx 报
upstream sent too big header - 此时调大
proxy_buffer_size(如设为128k)+proxy_buffers才有效 - 对超长 URL 转发无效,改它不会让
/api?data=xxx...30KB...通过
真正该调的两个指令:client_header_buffer_size 和 large_client_header_buffers
客户端请求行(含 method、URI、HTTP version)和请求头,由以下两个指令联合控制:
-
client_header_buffer_size:默认 1k,用于存储常规长度的请求头;若一行(如整个 URI)超过此值,Nginx 就换用large_client_header_buffers -
large_client_header_buffers:格式为large_client_header_buffers 4 8k,表示最多分配 4 个 8k 缓冲区来存超长请求头 - URI 长度不能超过单个 buffer 大小(即上面的
8k),且整行必须能放进一个 buffer(不跨 buffer)
✅ 正确做法:若 URL 最长可能达 16KB,建议配置:
client_header_buffer_size 2k;<br>large_client_header_buffers 4 16k;
这样单行最大支持 16KB,足够覆盖绝大多数超长参数场景(如地图坐标批量编码、加密 token 透传等)。
顺带检查:client_max_body_size 和 proxy_buffering
虽然和 URL 无关,但超长参数有时伴随大 body(如 JSON 内嵌长字符串),容易混淆:
-
client_max_body_size控制 request body 上限,不影响 URI;设太小会报413 Payload Too Large -
proxy_buffering off在调试时可临时禁用缓冲,避免因缓冲行为干扰排查,但生产慎用 - 确认后端本身是否有限制(如 Spring Boot 的
server.max-http-header-size),Nginx 调大只是第一步
验证是否生效的小技巧
修改后 reload Nginx,用 curl 构造超长 URL 测试:
curl -v "http://your-domain.com/test?$(python3 -c 'print(\"a\"*12000)')"
- 成功返回后端响应 → 配置生效
- 仍报
414→ 检查是否写在正确的http/server/location块(需在接收请求的层级设置) - 报
502 Bad Gateway→ 可能是后端拒绝,非 Nginx 问题,抓包看 upstream 日志


















