VPS 教程
VPS Nginx 报 400 Request Header Or Cookie Too Large 怎么办(2026):Cookie 与请求头排查
网站登录后报 400、清 Cookie 后又复发?从实际请求头找到错误来源,讲清 Nginx 缓冲区数量与大小的区别,附本机对比实测、持久配置和登录验收方法。

网站昨天还能打开,今天登录后却出现 400 Bad Request,下面还有一行 Request Header Or Cookie Too Large?这通常是发给服务器的 Cookie 或其他请求头超过了接收限制。访客可以先用无痕窗口验证;站长需要找出过大的字段,再调整 Nginx 和应用配置。
如果只是想恢复访问,清除这个网站的 Cookie 后重新登录。如果登录几次又复发,继续查服务端。把 client_max_body_size 调大,解决的是上传文件的请求体限制,通常修不好这个报错。
用无痕窗口打开同一个完整网址,先不登录,再测试登录后的页面。如果无痕能访问、原窗口不行,到浏览器的站点设置里删除该域名的 Cookie,再重新打开。清除后可能需要重新登录,也可能丢失保存在 Cookie 里的购物车或偏好。
不需要清空所有网站的数据。如果登录后立刻报错,把发生问题的页面、时间和“未登录正常、登录后失败”的现象告诉站长。清 Cookie 能暂时缩小请求头,却不会改变服务器限制,也不会阻止应用继续生成过大的登录数据。
| 报错或日志 | 优先检查 | 对应的处理方向 |
|---|---|---|
| 400,页面明确写着 Header Or Cookie Too Large | 发给 Nginx 的 Cookie、Authorization 等请求头 | 请求头缓冲区、Cookie 和令牌大小 |
| 431 Request Header Fields Too Large | 返回错误的代理或应用 | 该层对单个字段或全部请求头的限制 |
| 414 URI Too Long | 路径和查询字符串 | 缩短 URL,确认请求行限制 |
| 413 Request Entity Too Large | 上传文件或提交的请求体 | 上传入口与应用的请求体限制 |
| 502,日志写 upstream sent too big header | 上游返回的响应头,例如 Set-Cookie | 响应头缓冲区与上游应用 |
400 本身不等于 Cookie 太大,格式错误等问题也能返回 400;要结合具体提示和日志。431 可以表示单个字段过大,也可以表示请求头总量过大,见 MDN 的 431 说明。
如果遇到的是上传报 413,可以直接沿用 Nginx、PHP 与 Cloudflare 上传限制排查。
在浏览器开发者工具的 Network 中选中失败请求,核对网址、状态码和 Request Headers。重点看 Cookie、Authorization,以及特别长的自定义字段。比较同一页面未登录和登录后的请求,比只看首页是否打开更有用。
多个小 Cookie 会一起发送,合并后也可能变成一个很长的 Cookie 请求头。同名 Cookie 如果使用了不同 Domain 或 Path,还可能在同一次请求里重复出现。只看 document.cookie 容易漏掉 HttpOnly Cookie,应以实际发出的请求为准。
在 VPS 上确认版本、有效配置和日志位置:
nginx -v
sudo nginx -T
sudo tail -n 100 /var/log/nginx/error.log
日志路径按实际配置替换。nginx -T 会展示展开后的配置和来源文件,可以据此找到生效的 http、server 与重复设置。记录字段名称和长度即可,分享输出前去掉 Cookie、令牌和配置里的凭据。
与请求头过大有关的日志可能包含 client sent too large header,但当前日志级别未必记录它,没找到这句话不能排除问题。如果访问日志已有 $upstream_status,可结合时间和后端日志判断请求是否到达应用;单看错误页上的 Nginx 字样无法确定是哪一层返回的。
Nginx 官方默认配置是:
client_header_buffer_size 1k;
large_client_header_buffers 4 8k;
1k 是开始读取请求头时使用的缓冲区,装不下时可以按需申请较大的缓冲区,不是请求头只能有 1KB。4 8k 则表示最多使用 4 个 8KB 的大缓冲区。
对 HTTP/1.1,单个请求头字段需要放进一个大缓冲区。一个 Cookie 字段超过 8KB,即使改成 8 8k,也不会因此得到一个 64KB 的连续空间。官方参数说明还区分了请求行过长返回 414、请求头字段过长返回 400。
为这篇文章做了一个本机隔离测试:Nginx 1.19.6、HTTP/1.1,把 5 个各含 1800 个 ASCII 字符的模拟 Cookie 合并发送,Cookie 头值为 9023 字节。测试端点正常返回 204,结果如下:
| 缓冲区设置 | 不带 Cookie | 带 9023 字节模拟 Cookie |
|---|---|---|
4 8k | 204 | 400,显示 Cookie 过大提示 |
8 8k | 204 | 400,仍未通过 |
4 16k | 204 | 204,通过接收检查 |
这是旧版本上验证 HTTP/1.1 参数区别的测试,生产环境仍应使用受维护的版本。204 只说明模拟请求被接收,不代表真实登录业务已经恢复;HTTP/2、HTTP/3 还要按实际版本和协议验证。
如果正常业务确实需要超过当前限制的请求头,可以先把单个大缓冲区从 8KB 增至 16KB,并继续检查应用为什么产生这些数据。16KB 是这里的验证起点,需要按实际长度、流量和其他代理限制决定。
以下是放入现有 http 块的片段,找到原有指令后修改,别再添加一个重复的 http 块:
client_header_buffer_size 1k;
large_client_header_buffers 4 16k;
这两个指令只支持 http、server 上下文,不能放进 location。放在 http 会让没有单独覆盖设置的站点继承它,适合需要统一限制的实例;同机有多个站点时要评估影响。若只设置某个 server,还要核对默认站点、SNI、Host 与请求头处理阶段,详见 虚拟主机选择规则。
先备份实际要编辑的文件。下面以 /etc/nginx/nginx.conf 为例,修改站点文件时替换路径,并使用新的备份名:
sudo cp -a /etc/nginx/nginx.conf /etc/nginx/nginx.conf.header-backup-20261109
编辑并保存后执行:
sudo nginx -t
只有出现配置检查成功提示,才继续平滑重载:
sudo systemctl reload nginx
如果需要回滚,恢复备份,再检查成功后重载。大缓冲区按需分配,但高并发大请求仍会增加内存占用,不建议直接照搬 16 128k 之类的巨大参数。
Nginx 跑在 Docker 里时,编辑宿主机挂载的配置源文件。假设 Compose 的服务名是 nginx,检查成功后再执行重载:
docker compose exec nginx nginx -t
docker compose exec nginx nginx -s reload
服务名按项目替换。直接改容器里的临时文件,重建后可能丢失;宝塔、1Panel 或 Nginx Proxy Manager 用户也要找到面板支持的持久配置入口,确认该入口所处的上下文允许这些指令。
缓冲区调大后能访问,并不代表 Cookie 应该继续增长。常见来源是把完整用户资料、权限列表或购物车塞进 Cookie,登录令牌包含大量角色,以及旧插件不断留下不同路径的同名 Cookie。
优先减少不必要的字段,或在应用支持时改用较短的会话标识,把详细数据放在服务端。淘汰旧 Cookie 时,删除操作要匹配原来的 Domain 和 Path。登录方案的修改还要确认退出、续期与权限校验保持正确。
链路如果是“浏览器 → CDN → Nginx → 应用”,每层都可能有限制。外层已经拒绝,调大源站无效;Nginx 接收成功,后端仍可能返回 431。按同一个失败请求逐层核对,不要把代理层的错误都归到 VPS 上。
还有一个容易混淆的情况:日志写着 upstream sent too big header。那是 Nginx 读取上游响应时的问题,可能涉及较大的 Set-Cookie,应检查应用响应与 proxy_buffer_size,而不是继续加大客户端请求头缓冲区,见 proxy_buffer_size 的定义。
用原来出错的窗口测试,保留原请求作为对照,再用干净窗口登录、刷新后台、退出并重新登录。确认请求头大小稳定,失败请求消失,后端也收到正确的请求。只用一个不带 Cookie 的 curl 打开首页,验不出原来的登录问题。
现代 Nginx 不要照搬旧教程里的 http2_max_field_size 和 http2_max_header_size:两者自 1.19.7 起已经废弃,官方改为使用 large_client_header_buffers,见 HTTP/2 模块文档。参数生效与否,应在实际使用的协议上复测。
你下一步可能需要: