
上传图片、安装包或网站备份时,页面突然返回 413 Request Entity Too Large,通常不是文件损坏,也不代表后端程序已经接收了文件。更常见的情况是:请求体还没到达应用程序,就被 Nginx、Ingress、CDN 或上游网关中的某一层拦下了。
处理这类问题,不能只在网上抄一行 client_max_body_size 100M;。同一套业务可能经过 CDN、负载均衡、外层 Nginx、容器 Ingress 和 PHP 等多层组件,任何一层的限制更小,上传都会失败。下面按实际排查顺序说明应该查哪里、怎么改,以及改完后如何确认配置确实生效。
413错误表示什么
HTTP 413 表示服务器拒绝处理过大的请求内容。对文件上传来说,请求体里通常包含文件数据,所以它最容易在上传大文件时出现。
如果请求由 Nginx 拒绝,错误日志里经常能看到类似内容:
client intended to send too large body: 52428800 bytes
这行日志比浏览器里的错误页更有价值。它说明请求已经到达当前 Nginx,并且 Nginx 认为请求体超过了允许值。先确认这一点,可以避免一开始就去改 PHP、WordPress 或应用代码。
第一步:确认是哪一层返回了413
先查看 Nginx 错误日志。常见位置包括:
sudo tail -n 100 /var/log/nginx/error.log
sudo journalctl -u nginx --since "30 minutes ago"
如果站点使用了单独的错误日志,应以虚拟主机配置中的 error_log 路径为准。可以通过下面的命令展开当前 Nginx 实际加载的全部配置:
sudo nginx -T
nginx -T 会在检查语法的同时输出完整配置,适合查找这些内容:
sudo nginx -T 2>&1 | grep -n "client_max_body_size"
sudo nginx -T 2>&1 | grep -n "server_name example.com"
如果错误日志中没有“too large body”之类的记录,或者请求根本没有到达这台服务器,就要继续检查外层 CDN、云负载均衡、WAF、API 网关或 Kubernetes Ingress。不要因为网站后端使用 Nginx,就默认 413 一定由最里面的 Nginx 返回。
第二步:正确设置client_max_body_size
Nginx 使用 client_max_body_size 限制客户端请求体大小。官方文档给出的默认值是 1m,该指令可以写在 http、server 或 location 上下文中。
例如,把整个 Nginx 实例的默认限制调整为 50 MB:
http {
client_max_body_size 50m;
# 其他配置
}
只调整某个网站,可以写在对应的 server 中:
server {
listen 443 ssl;
server_name example.com;
client_max_body_size 50m;
location / {
proxy_pass http://127.0.0.1:8080;
}
}
如果只有上传接口需要较大限制,范围可以收得更小:
server {
listen 443 ssl;
server_name example.com;
client_max_body_size 10m;
location /api/upload/ {
client_max_body_size 100m;
proxy_pass http://127.0.0.1:8080;
}
}
这种写法比全站统一放宽更稳妥。普通页面仍保持 10 MB,只有明确的上传接口允许 100 MB 请求。
配置层级为什么容易改错
client_max_body_size 会按照 Nginx 的配置层级生效。实际请求匹配到哪个 server 和 location,就要看这些位置是否存在更具体的设置。
常见误区有三个:
- 修改了
/etc/nginx/nginx.conf,但站点实际由面板生成的虚拟主机配置控制。 - 在
server中设置了 100 MB,上传路径对应的location又写了更小的值。 - 服务器上安装了两套 Nginx,修改的是一套配置,运行中的服务读取的是另一套配置。
因此,改完后最好再次运行 nginx -T,确认新值确实出现在运行中配置里,而不是只检查某个文件。
第三步:检查语法并平滑重载
不要直接重启服务。先检查配置语法:
sudo nginx -t
看到 syntax is ok 和 test is successful 后,再平滑重载:
sudo systemctl reload nginx
也可以使用 Nginx 自带的信号命令:
sudo nginx -s reload
重载后重新上传同一个文件,并同时观察错误日志:
sudo tail -f /var/log/nginx/error.log
如果 413 消失,但随后出现 502、504 或应用层报错,说明请求已经通过 Nginx,问题转移到了后端服务。此时应继续检查应用自身的上传限制、超时和存储目录,而不是反复增大 client_max_body_size。
PHP网站还要检查两个参数
WordPress、Typecho、Laravel 等 PHP 网站还受 PHP 配置影响。最常见的两个参数是:
upload_max_filesize = 50M
post_max_size = 60M
upload_max_filesize 控制单个上传文件的最大值;post_max_size 控制整个 POST 请求的最大值。一个请求可能还包含表单字段和多个文件,所以 post_max_size 通常应不小于 upload_max_filesize,实际配置时应留出一定余量。
修改后要重载对应版本的 PHP-FPM,例如:
sudo systemctl reload php8.3-fpm
服务名要以服务器实际安装版本为准,可以使用下面的命令查看:
systemctl list-units --type=service | grep php.*fpm
Nginx 限制和 PHP 限制的表现不完全一样。Nginx 在接收阶段拒绝请求时,常见结果是直接返回 413;PHP 限制过小时,请求可能已经进入 PHP,但上传文件为空、表单数据不完整,或由程序显示自己的错误提示。
反向代理、CDN和Ingress要逐层检查
一条实际上传链路可能是:
浏览器 -> CDN/WAF -> 云负载均衡 -> 外层Nginx -> Ingress -> 应用服务
最终可上传的大小由链路中最小的限制决定。内层 Nginx 允许 100 MB,并不代表外层网关也允许 100 MB。
多层Nginx
如果前后有两层 Nginx,两层都要检查。判断当前日志属于哪一层时,可以结合服务器 IP、日志时间、请求路径和响应头排查。
Kubernetes Ingress NGINX
使用 ingress-nginx 时,单个 Ingress 可以通过注解设置代理请求体大小:
metadata:
annotations:
nginx.ingress.kubernetes.io/proxy-body-size: "50m"
修改后应确认资源已经应用,并查看 Ingress Controller 生成的实际配置。不同 Ingress 实现的注解和默认值可能不同,不要把 ingress-nginx 的参数直接套到其他控制器上。
CDN、WAF和云网关
这类托管服务通常有产品级请求大小上限,部分限制不能通过源站配置突破。遇到这种情况,可以考虑直传对象存储、分片上传,或为大文件上传使用不经过该代理层的专用域名。具体上限应以当前服务商和套餐的官方文档为准。
不要把client_body_buffer_size当成上传上限
client_body_buffer_size 决定读取请求体时使用多大的缓冲区。请求体大于缓冲区时,Nginx 可以把全部或部分内容写入临时文件,它并不等于允许上传的最大文件大小。
如果已经确认错误是 client intended to send too large body,应优先检查 client_max_body_size。随意增大缓冲区可能增加内存占用,却不能解决真正的限制问题。
大文件上传还要留意临时目录空间和权限。Nginx 需要落盘缓冲时,磁盘空间不足或 client_body_temp_path 不可写,也会导致上传失败,但这类问题通常不会表现为标准的 413。
是否可以直接设置为0
Nginx 官方文档说明,把 client_max_body_size 设置为 0 可以关闭请求体大小检查:
client_max_body_size 0;
生产环境一般不建议为了省事直接这样设置。取消限制后,恶意或异常客户端可能持续提交超大请求,占用带宽、临时磁盘、连接和后端处理资源。更合理的做法是根据业务文件类型设置明确上限,并只对上传接口放宽。
例如,网站只允许上传最大 20 MB 的图片,可以将 Nginx 设置为 25 MB 左右,应用层仍保留 20 MB 的业务校验。代理层留出协议和表单开销,应用层负责给用户返回清楚的文件大小提示。
改完仍然报413的检查清单
可以按下面的顺序逐项确认:
- Nginx 错误日志是否出现
client intended to send too large body。 nginx -T输出中,目标server和上传location的限制是多少。nginx -t是否通过,配置是否已经 reload。- 请求是否还经过 CDN、WAF、负载均衡、API 网关或另一层 Nginx。
- Kubernetes 使用的是哪一种 Ingress Controller,对应注解是否正确。
- PHP 的
upload_max_filesize和post_max_size是否足够。 - 应用框架、CMS 或插件是否还有独立的文件大小限制。
- 大文件是否导致代理超时、临时目录空间不足或后端存储失败。
- DNS 是否仍指向旧服务器,修改的机器是否真正接收了当前请求。
413 的处理思路可以概括为一句话:先用日志确认拦截层,再在最小必要范围内调整限制。只修改一个看起来像 Nginx 配置的文件,往往是“已经设置 100M,上传仍然失败”的根源。
参考资料
- Nginx 官方文档:Module ngx_http_core_module(
client_max_body_size、client_body_buffer_size)
https://nginx.org/en/docs/http/ngx_http_core_module.html - Nginx 官方文档:Command-line parameters(
-t、-T、-s reload)
https://nginx.org/en/docs/switches.html - PHP 官方文档:Core php.ini directives(
post_max_size)
https://www.php.net/manual/en/ini.core.php - PHP 官方文档:Handling file uploads(
upload_max_filesize)
https://www.php.net/manual/en/features.file-upload.common-pitfalls.php - Ingress NGINX Controller 官方文档:Annotations(
proxy-body-size)
https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#custom-max-body-size
核验日期:2026年8月24日




