现场是这样的。CentOS 7.9 + nginx 1.18 反代 Java 后端,登录之后跳转的页面固定五零二,error.log 写 upstream sent too big header while reading response header from upstream,其他页面完全正常。

中间走过弯路,把「JWT 直接放在头里,token 越长越容易触发,越权字段越多越明显」当成主因,改完现象没变。

真正麻烦的地方在于,几个原因的现象几乎一样。登录成功时后端往响应头里塞了整段权限 JSON 和多个 Set-Cookie,头部超过四 K;proxy_buffer_size 只管响应头,默认值只有 4k 或 8k,装不下就判为非法响应;加了一层网关又追加了几个自定义头,叠加之后超限。

动手时先在错误日志里确认是头部超限

grep -c 'too big header' /var/log/nginx/error.log

实测一次响应头的大小

curl -sI -b /tmp/cookie.txt http://127.0.0.1/login | wc -c

接着把响应头缓冲单独调大,别只动 body 缓冲

sed -i '/proxy_pass/i\        proxy_buffer_size 32k;\n        proxy_buffers 8 32k;' /etc/nginx/conf.d/portal.conf && nginx -t && nginx -s reload

末了让后端把大字段从头里挪出去

curl -sI http://127.0.0.1/login | awk '{print length($0), $1}' | sort -rn | head -3

别只看报错消失,验证要多做一步。登录跳转页返回 200,error.log 里不再新增 too big header,响应头里的 Set-Cookie 数量与长度回落到正常范围。

补一句。调大缓冲区只是止血,头里塞业务数据迟早再撞上限,能让后端把权限数据放到响应体里就别放头里。报错文案容易误导,真正的原因往往在相邻那一层的日志里。

作者 9823189