必须在location块中显式配置client_max_body_size,否则仍报413;还需同步调大client_body_buffer_size、确保client_body_temp_path权限正确、延长proxy_read_timeout等超时参数,并校准后端限制与请求头缓冲,否则会因缓冲、权限、超时或头部过大导致413/500/502/400错误。

只改 client_max_body_size 很大概率还是报 413 —— 它只是“门禁”,后面还有缓冲、超时、磁盘权限、请求头限制、后端限制五道关卡。
必须写在 location 块里才真正生效
很多人把 client_max_body_size 放在 http 或 server 块里,结果上传接口仍返回 413。根本原因是:Nginx 匹配优先级是 location > server > http,而你调用的是 /api/upload 这类路径,如果该 location 块没显式设置,就继承默认值(1m)。
- ✅ 正确写法:
location /api/upload {<br> client_max_body_size 500m;<br> proxy_pass http://backend;<br>} - ⚠️ 不推荐仅在
server块设 —— 整个域名下所有 POST 都放宽,包括登录、表单等非上传接口,扩大攻击面 - ❌ 典型错误:在
http块设了client_max_body_size 100m,但location /里没重写,实际走的仍是默认 1m
配套参数不调,大文件照样中断或 500
client_max_body_size 只管“容不容”,不管“稳不稳”。上传耗时长、数据量大,必须同步调以下三项:
-
client_body_buffer_size:建议设为512k~1m。太小(如默认8k)会导致频繁刷盘;太大浪费内存。设成和client_max_body_size一样会强制全程走内存(仅适合小流量) -
client_body_temp_path:确认路径(默认/tmp)磁盘空间够,且 Nginx 运行用户(如www-data或nginx)有读写权限,否则日志里会出现open() failed (13: Permission denied) -
proxy_read_timeout和proxy_send_timeout:建议设为3600(1 小时)。Nginx 在转发给后端前需完整接收请求体,超时会直接断连,前端看到的是网络失败而非 413
别漏掉请求头大小限制,它会静默拦截
当 POST 请求带大量自定义 header(比如 JWT、长 Cookie、多层代理头),可能触发 400 Bad Request 或连接被关,但日志里往往只显示 client sent too large request,根本不会走到 body 校验那步。
-
large_client_header_buffers控制单个请求行 + 所有请求头能占多大内存,默认是4 8k(共 32KB 上限) -
client_header_buffer_size是第一个 buffer 大小(默认1k),不够时才会分配large_client_header_buffers,两者要配套看 - 临时调试可设为
large_client_header_buffers 8 16k;,但别长期用过大的值,会增加内存压力
验证不能只靠浏览器点选,得看日志和真实请求
测试必须用真实 multipart 请求,不能只靠页面上传按钮:
- 用
curl -F "file=@test.zip" http://host/api/upload发请求,观察响应码是否为 200 - 查日志比看页面更准:
tail -f /var/log/nginx/error.log里出现client intended to send too large body就说明限制起效了 - 注意单位拼写:
0.5g合法,500mb合法,但500MB和500Mb容易因大小写疏忽失效 - 若设为
client_max_body_size 0表示禁用检查,生产环境慎用——必须确保后端有校验兜底,否则可能被恶意上传打满磁盘
最常被忽略的是:Nginx 放行之后,后端服务(如 Spring Boot 的 spring.servlet.context-parameters.max-http-form-post-size、FastAPI 的 max_upload_size、Node.js 的 body-parser 限制)依然可能拒绝请求。Nginx 的限制值应略大于后端限制,留出缓冲余量。











