必须在location块中显式配置client_max_body_size才能生效,因为Nginx按“就近原则”匹配,不继承父级配置;仅设在http或server块会导致上传路径仍用默认1MB,且需同步调优buffer、timeout、temp_path权限及后端限制。

只改 client_max_body_size 九成会失败——它只是“门禁”,不是“整条通道”。
为什么 location 块里必须显式写 client_max_body_size
Nginx 的匹配逻辑是“就近生效”,client_max_body_size 不会自动继承父级配置。比如你上传接口路径是 /api/upload,但只在 http 块里设了 client_max_body_size 500m,而 location /api/upload 块里没重写,那它实际用的是默认的 1m(不是你设的 500m)。
- ✅ 正确做法:在对应
location块内直接写,例如location /api/upload { client_max_body_size 500m; proxy_pass http://backend; } - ⚠️ 慎用 server 级设置:若整个
server块都设大值,登录、表单等非上传接口也会被放宽,攻击面变宽 - ❌ 错误典型:把
client_max_body_size放在http块末尾,以为“全局生效”,结果所有上传路径仍报413
client_max_body_size 生效后,为什么还卡在 413 或 500?
这个参数只拦“太大”,不保“稳传”。真正上传时,Nginx 还要缓存 body、写临时文件、等后端响应——任一环节出问题都会中断,且错误码可能不是 413(比如 500 或连接超时)。
-
client_body_buffer_size建议设为512k~1m:太小(如默认8k)会导致频繁刷盘;太大浪费内存;设成和client_max_body_size一样值可强制走内存,但仅适合低流量场景 -
client_body_temp_path路径(默认/tmp)必须确保 Nginx 运行用户(如www-data)有读写权限,否则日志里会报open() failed (13: Permission denied) -
proxy_read_timeout和proxy_send_timeout至少设为3600:Nginx 在转发前需完整接收 body,超时就断连,前端看到的是网络失败,不是 413
header 太大也会触发 400,和 client_max_body_size 无关
POST 请求如果带大量自定义 header(JWT token 长、多层代理头、超长 Cookie),可能根本进不了 body 校验阶段,Nginx 就在解析 header 时拒绝请求,返回 400 Bad Request,日志里常见 client sent too large request 或静默丢包。
-
client_header_buffer_size是第一个 buffer,默认1k;不够时才启用large_client_header_buffers - 检查 error log 是否有
request header or cookie too large提示 - 临时调试可设
large_client_header_buffers 8 16k,但别长期用过大值,内存压力会上升
验证是否真生效,别只靠浏览器点选
浏览器上传控件常走 JS 分片或封装,掩盖真实行为。真正校验得用原始 HTTP 请求打进去。
- 用
curl -F "file=@big.zip" http://your-domain/api/upload发 multipart 请求,看返回码 - 查
tail -f /var/log/nginx/error.log:出现client intended to send too large body才说明限制起效了 - 改完配置必须
nginx -t && nginx -s reload;某些旧版本 reload 不生效,得killall nginx && nginx - 注意单位大小写:
20m合法,20M会报配置错误;0.5g、500mb都行,但500MB容易因大小写疏忽失效
最常被跳过的其实是 client_body_temp_path 权限和 proxy_read_timeout,这两项不出错不报警,但一上传就断——得盯着 error log 里有没有磁盘或超时相关提示,而不是只盯着 413。











