nginx 413 Request Entity Too Large: A 5-Minute Diagnosis and Fix Guide
If you are in the middle of an incident, start here: If nginx
error.logshowsclient intended to send too large body, it is 99% aclient_max_body_sizeproblem (default 1MB). Putclient_max_body_size 50m;in thelocationblock that handles uploads, then runnginx -t && systemctl reload nginx. Below we cover the exact placement plus every other layer that can still block you—all in five minutes.
Uploads that worked a minute ago suddenly return 413?
When the ticket is “image uploads were fine yesterday and suddenly broke today,” look at the status code first. 413 is fundamentally different from 502/504.
- 502/504: The gateway cut the connection because the upstream is down or too slow (a backend problem)
- 413 Request Entity Too Large: The request body the client sent is too large, so nginx aborted before it even finished reading the body
So 413 can fire even when the backend is healthy. The usual reason it “suddenly” happens is that uploaded file size crossed the limit. A 1MB thumbnail goes through; a 1.2MB photo does not.
This article covers 413 caused by request body size only. For 504/502 (timeouts, upstream down), see the separate guide (
nginx 502/504 troubleshooting).
Why 413 fires: the mechanism
nginx has a client_max_body_size directive whose default is only 1MB. When a request arrives, nginx looks at the Content-Length header (or the accumulated size of a multipart body) and, the moment that limit is exceeded, it stops reading the body and immediately responds with 413.
The request is not rejected at a single point. Body-size limits exist at several layers.
Browser ──> CDN/WAF ──> nginx ──> reverse proxy ──> upstream (PHP/app)
(body limit) (1MB) (proxy limit) (post_max_size, etc.)If any one of those limits is too small, 413 is returned there. So the key is to pin down which layer blocked the request first.
5-minute diagnosis routine
① Check one line in error.log
tail -f /var/log/nginx/error.log | grep "too large body"If you see a line like this, nginx is the culprit.
*123 client intended to send too large body: 3145728 bytes② Reproduce with curl
curl -v -F "file=@/path/big.jpg" https://example.com/uploadUse -v to inspect the response in detail. Two things matter:
- Status code:
HTTP/1.1 413 Request Entity Too Large Serverheader:Server: nginxmeans nginx,Server: cloudflaremeans CDN/WAF, anything else may be the upstream
③ Identify which layer is blocking
| Response body message | Server header | Who is blocking | Action |
|---|---|---|---|
413 Request Entity Too Large | nginx | nginx | Raise client_max_body_size |
413 Payload Too Large | app/framework | upstream (app) | post_max_size, app limits |
413 + cloudflare/WAF | CDN/WAF | front layer | CDN body-size policy |
Check the currently applied nginx value like this.
nginx -T | grep client_max_body_sizeIf nothing is printed, the default of 1MB is in effect.
Fixes by layer
nginx: which block to put it in
client_max_body_size is inherited http → server → location, and overridden by a more specific block. The safest approach is to set a large value only on the upload endpoint location.
http {
client_max_body_size 1m; # keep global small
server {
server_name example.com;
client_max_body_size 10m; # default for this server
location /upload {
client_max_body_size 50m; # allow large uploads only here
}
}
}With the config above, /upload allows up to 50MB, other paths on this server 10MB, and other servers 1MB. Always syntax-check, then reload.
nginx -t && systemctl reload nginxIf you are on Kubernetes (nginx-ingress)
In container environments the same issue often comes back because of a missing annotation. Add this to the Ingress:
metadata:
annotations:
nginx.ingress.kubernetes.io/proxy-body-size: "50m"Align the upstream as well
Raising nginx alone still yields 413 if the upstream blocks. The recommended alignment is nginx ≥ post_max_size ≥ upload_max_filesize.
| Target | Setting | Example | Notes |
|---|---|---|---|
| nginx | client_max_body_size | 50m | Outermost, largest |
| PHP | post_max_size | 50M | Entire POST body |
| PHP | upload_max_filesize | 48M | Per-file |
| Apache | LimitRequestBody | 52428800 | In bytes |
| nginx→FastCGI | fastcgi_buffers, etc. | sized appropriately | Temp files if buffers are too small |
If you raise nginx to 50m but leave PHP post_max_size at 2M, nginx lets the request through, then PHP discards the body and $_FILES comes back as an empty array—a classic trap.
The danger of client_max_body_size 0
0 means unlimited. Never set it globally. An attacker can send a multi-GB body, exhaust disk and memory, and take the service down.
When multipart and timeouts fire together
Large uploads can hit size limits and time limits at the same time. The body limit may be large enough, but a slow link stretches the transfer until client_body_timeout (default 60s) fires, producing a 408 or a dropped connection.
location /upload {
client_max_body_size 50m;
client_body_timeout 120s; # allow slow uploads
}413 (size) and timeouts (time) are different directives—check both. If the response is 502/504, this article is not the one you need; troubleshoot the upstream instead.
A note from the field
After enough incidents, the pattern is clear: 80% of 413 tickets become a second outage because “we fixed nginx but not PHP/the proxy.” It also comes back right after a new CDN is attached, or after a deploy that forgot the ingress annotation. So when I fix a 413 I always use a checklist: write down every body-size limit on the path (browser → CDN → nginx → app) and align them in one pass. Fix only one layer and you will meet this again next week.
Recurrence-prevention and security checklist
- Never use
client_max_body_size 0(unlimited) - Apply large values only on the upload
location; keep the global default small - Confirm nginx ≥
post_max_size≥upload_max_filesize - On Kubernetes, confirm the
proxy-body-sizeannotation - Check any separate body-size limit on the CDN/WAF in front
- Apply auth, extension checks, and virus scanning on the upload endpoint
- Monitor and alert on temp-directory disk exhaustion
References: official docs
The primary source for the behavior, settings, and errors in this article is the official documentation below. Check version-specific options and exact behavior there.
FAQ
Q. I changed client_max_body_size and still get 413.
A. Check where it was applied. Use nginx -T | grep client_max_body_size to see the actually loaded value, and verify whether the upload location inherits from a different server or parent block. Also suspect ingress/CDN front-end limits and PHP post_max_size.
Q. How do I tell 413 from 504?
A. 413 means “body too large”—nginx aborts immediately. 504 means the upstream is slow or dead. Distinguish them by status code and whether error.log contains too large body. For 504, see the separate guide.
Q. Do I have to restart nginx to apply the change?
A. A restart is not required. Validate syntax with nginx -t, then do a zero-downtime reload with systemctl reload nginx.
Nodelog는 모든 콘텐츠의 내용과 출처를 공개 전에 검토합니다. 환경(OS·버전)에 따라 결과가 달라질 수 있는 기술 정보는 공식 문서와 함께 확인하며, 검토 기준과 정정 원칙은 편집 정책에서 안내합니다. 오류를 발견하시면 이메일로 제보해 주세요 — 확인 후 신속히 정정합니다.
Comments
Be the first to comment.