--limit-max-requests控制worker处理请求数上限,与请求体大小无关;真正限制请求头的是--limit-request-field-size和--limit-request-fields;请求体大小需由Nginx、FastAPI(如UploadFile.max_size)及云代理三层协同控制。

Uvicorn 启动时用 --limit-max-requests 不能限制请求体大小
这个参数实际控制的是每个 worker 处理的请求数上限,和请求体(body)大小完全无关。混淆它会导致配额误调,413 错误依然出现。真正管请求体大小的是 --limit-request-field-size 和底层 ASGI 协议栈的解析逻辑——但注意,Uvicorn 自身**不直接暴露“最大上传体积”配置项**,它依赖 HTTP 协议实现(如 httptools 或 h11)对 header 和 body 的分段约束。
真正生效的两个关键参数:--limit-request-field-size 和 --limit-request-fields
它们共同影响大文件上传能否抵达应用层:
-
--limit-request-field-size:限制单个 HTTP 请求头字段值的最大字节数,默认 8190。如果上传请求带了超长Authorization或自定义 header,可能在此被截断 -
--limit-request-fields:限制请求头中字段总数,默认 100。某些前端 SDK 会塞大量 trace header,触达此限后连接直接关闭,不会进路由
这两个参数作用于解析阶段,早于 FastAPI 的 Request.body() 调用。若你看到日志里有 invalid HTTP header 或连接重置(非 413),大概率是它们卡住了。
业务层必须补上 FastAPI 的 Request 解析限制
Uvicorn 不校验 body 总大小,只负责把已接收的字节流交给 ASGI app。所以 413 真正由框架层抛出时,往往是因为:
Uvicorn 0.52.1 是 Python ASGI Web 服务器,提供异步应用服务及 WebSocket 支持,常用于 FastAPI、Starlette 等应用的开发和部署。本下载为官方 PyPI 通用 wheel 包,可使用 pip 安装,并由包管理器处理所需依赖。
- FastAPI 默认使用
Starlette的Request.form()或Request.body(),而后者默认无上限,但实际受内存和超时制约 - 更常见的是显式用了
File或UploadFile,此时需手动加max_files/max_file_size参数 - 例如:
async def upload(file: UploadFile = File(..., max_size=20_000_000))—— 这个max_size才是面向用户的上传配额
漏掉这步,Uvicorn 就算放行了,应用也可能因 OOM 被系统 kill,或者在读 body 时抛 ConnectionResetError。
别忘了 Nginx 或 Cloud Load Balancer 的前置拦截
如果你部署在反向代理后,client_max_body_size(Nginx)、max_request_bytes(Cloudflare)、requestTimeout(ALB)这些配置优先级高于 Uvicorn 和 FastAPI。日志里出现 413 Request Entity Too Large 且 body_bytes_sent=0,基本说明请求根本没到 Uvicorn 进程。
最稳妥的做法是三层对齐:Nginx 配置略宽于业务层限制(比如 Nginx 设 25MB,FastAPI 设 20MB),再在 API 文档里明确标出客户端应遵守的上限值。否则前端传了 22MB 文件,Uvicorn 和 FastAPI 都没报错,却卡死在代理层,排查路径会绕远。










