Nginx出现413 Request Entity Too Large怎么办?上传大小限制与反向代理排查教程

Nginx上传文件时出现413错误,通常是请求体大小超过Nginx、Ingress或上游网关限制。本文介绍如何通过日志、nginx -T、client_max_body_size和PHP配置逐层定位并安全调整。

Nginx出现413 Request Entity Too Large怎么办?上传大小限制与反向代理排查教程

上传图片、安装包或网站备份时,页面突然返回 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,该指令可以写在 httpserverlocation 上下文中。

例如,把整个 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 的配置层级生效。实际请求匹配到哪个 serverlocation,就要看这些位置是否存在更具体的设置。

常见误区有三个:

  1. 修改了 /etc/nginx/nginx.conf,但站点实际由面板生成的虚拟主机配置控制。
  2. server 中设置了 100 MB,上传路径对应的 location 又写了更小的值。
  3. 服务器上安装了两套 Nginx,修改的是一套配置,运行中的服务读取的是另一套配置。

因此,改完后最好再次运行 nginx -T,确认新值确实出现在运行中配置里,而不是只检查某个文件。

第三步:检查语法并平滑重载

不要直接重启服务。先检查配置语法:

sudo nginx -t

看到 syntax is oktest 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的检查清单

可以按下面的顺序逐项确认:

  1. Nginx 错误日志是否出现 client intended to send too large body
  2. nginx -T 输出中,目标 server 和上传 location 的限制是多少。
  3. nginx -t 是否通过,配置是否已经 reload。
  4. 请求是否还经过 CDN、WAF、负载均衡、API 网关或另一层 Nginx。
  5. Kubernetes 使用的是哪一种 Ingress Controller,对应注解是否正确。
  6. PHP 的 upload_max_filesizepost_max_size 是否足够。
  7. 应用框架、CMS 或插件是否还有独立的文件大小限制。
  8. 大文件是否导致代理超时、临时目录空间不足或后端存储失败。
  9. DNS 是否仍指向旧服务器,修改的机器是否真正接收了当前请求。

413 的处理思路可以概括为一句话:先用日志确认拦截层,再在最小必要范围内调整限制。只修改一个看起来像 Nginx 配置的文件,往往是“已经设置 100M,上传仍然失败”的根源。

参考资料

核验日期:2026年8月24日

数据库运维知识库

Redis出现MISCONF错误怎么办?RDB持久化失败、磁盘权限与写入恢复教程

2026-8-21 17:40:07

实操指南知识库

基于云服务器的SpringCloud微服务部署

2024-12-16 14:59:50