client_max_body_size 是 nginx 限制 http 请求体(如 post/put 数据)最大字节数的指令,可在 http、server 或 location 块中配置,作用域内生效,不自动继承父级,默认值为 1m;若超出则返回 413 错误。

client_max_body_size 是什么,设在哪才生效
client_max_body_size 控制的是 HTTP 请求体(即 POST/PUT 的 body)最大允许字节数。它不是全局开关,而是作用域敏感的指令:写在 http 块里影响所有 server;写在 server 块里只影响该虚拟主机;写在 location 块里仅对匹配路径生效。
常见错误是只改了 http 块,但后端路由走的是某个特定 location,而该 location 没有显式继承或覆盖该值——Nginx 不会自动继承父级的 client_max_body_size,它默认为 1M,且不向上查找。
- 要支持 20MB 文件上传,推荐在对应
location中直接写:client_max_body_size 20m; - 如果多个上传接口分散在不同路径,不如统一写在
server块里更稳妥 - 注意单位大小写:
20m合法,20M会报配置错误
为什么调大了 client_max_body_size 还报 413
除了 body 大小,Nginx 对请求头(headers)也有独立限制,当 POST 请求带大量自定义 header(比如 JWT、长 Cookie、多层代理头),可能触发 400 Bad Request 或静默截断,但更典型的是——large_client_header_buffers 不足导致连接被关,日志里却只显示 “client sent too large request” 或干脆无记录。
这个参数控制单个请求行 + 所有请求头能占多大内存,默认是 4 8k(即最多 4 个 8KB buffer,共 32KB 上限)。如果 header 总长超限,Nginx 在解析阶段就拒绝请求,根本不会走到 body 校验那步。
- 检查 error log 是否有
400 "request header or cookie too large"类似提示 - 临时调试可设为
large_client_header_buffers 8 16k;,但别长期用过大的值,会增加内存压力 -
client_header_buffer_size是第一个 buffer 大小(默认 1k),它不够时才会分配large_client_header_buffers,所以两者要配套看
proxy_pass 转发 POST 时,后端收不到数据的真相
Nginx 默认会把原始请求的 Content-Length 和 Transfer-Encoding 头透传给后端,但如果用了 proxy_buffering off 或启用了某些压缩/重写模块,可能导致 body 被提前消费或丢弃。更隐蔽的问题是:当 Nginx 需要读取完整 body(比如做鉴权、日志记录、WAF 规则匹配)时,它必须先把整个 body 缓存在内存或临时文件里——这时如果 client_max_body_size 没设够,或磁盘空间不足(client_body_temp_path 所在分区满),就会返回 413,即使你后端其实能接更大请求。
- 确认
client_body_temp_path指向的目录有足够空间和写权限(默认在 nginx 安装目录下的client_body_temp) - 避免在
location中混用proxy_buffering off和大 body 转发,二者冲突容易丢数据 - 后端若用 Node.js/Python 等框架,还需检查其自身 body 解析限制(如 Express 的
bodyParser.limit、Flask 的MAX_CONTENT_LENGTH),Nginx 只管“送到门口”,不管“进门后怎么拆包”
并发上传时容易忽略的系统级瓶颈
调大 Nginx 参数只是第一步。Linux 内核对单进程打开文件数、网络连接队列、临时端口范围都有默认限制,高并发上传下,client_max_body_size 100m 设得再大,也可能卡在:accept() failed (24: Too many open files) 或大量 TIME_WAIT 占满端口。
这些不是 Nginx 配置能解决的,必须同步调整内核参数:
-
fs.file-max = 999999(系统级最大文件句柄) -
net.core.somaxconn = 65535(连接等待队列长度) -
net.ipv4.ip_local_port_range = 1024 65000(避免端口耗尽) - 上传过程中大量短连接会快速堆积
TIME_WAIT,需开net.ipv4.tcp_tw_reuse = 1
这些改完要执行 sysctl -p 生效,且需确保 nginx worker 进程的 ulimit -n 也同步调高,否则 Nginx 自己打不开那么多 socket。











