Nginx "413 Request Entity Too Large": raise the upload limit in the right place
Fix 413 Request Entity Too Large on uploads: set client_max_body_size in nginx, then the limits of PHP, Node.js, the Kubernetes ingress and any proxy in front.
by OhSudo ··
Not sure this is your cause?Find it step by step: Website down →
Part of a learning path:Web servers: nginx and HTTPS in production
Small uploads work; a bigger file fails with:
413 Request Entity Too Largenginxnginx limits the size of a request body — an uploaded file, a large form, a big JSON payload — with client_max_body_size, and the default is only 1 MB. Anything bigger is rejected before your app even sees it. nginx’s error log confirms it:
2026/11/02 10:41:07 [error] 912#912: *218 client intended to send too large body: 15728640 bytes, client: 203.0.113.7, server: example.com, request: "POST /upload HTTP/1.1", host: "example.com"Raising the limit in nginx is usually the first step, but not always the last: every layer between the browser and your code may have its own limit.
- Browser upload15 MB filesends
- nginxclient_max_body_size: 1 MB(breaks here)413 before the app(fails)
- Your appits own limit comes next
TL;DR
server { # … client_max_body_size 50m;}sudo nginx -t && sudo systemctl reload nginx1. Set the limit in nginx
client_max_body_size works in the http, server and location blocks; the most specific one wins. Put it where it makes sense:
- in the
serverblock, for the whole site; - or only in the
locationthat handles uploads, keeping the small default elsewhere:
location /upload { client_max_body_size 200m; proxy_pass http://127.0.0.1:3000;}0 turns the check off — avoid it on public sites, it lets anyone send endless data. After the change, test and reload; a reload is enough:
sudo nginx -t && sudo systemctl reload nginxIf nothing changes, check that you edited the file nginx really uses and that no more specific block sets a smaller value: sudo nginx -T | grep -n client_max_body_size lists every one. The Nginx Config Generator has a “max upload size” field that sets it for you.
2. The next limit: your application
Once nginx lets the request through, the app may refuse it in its own way.
PHP (PHP-FPM) — two settings in php.ini (on Debian/Ubuntu /etc/php/8.3/fpm/php.ini), and post_max_size must be at least as big as upload_max_filesize:
upload_max_filesize = 50Mpost_max_size = 55MThen sudo systemctl restart php8.3-fpm (or php-fpm on RHEL). A too-small PHP limit doesn’t always show an error: the upload may simply arrive empty.
Node.js / Express — the JSON parser’s default limit is 100 kB, and the error looks almost the same: PayloadTooLargeError: request entity too large, status 413 — but from Express, not nginx. Raise it where the parser is set up: app.use(express.json({ limit: '10mb' })). File uploads with a library like multer have their own limits.fileSize.
Other frameworks have similar settings: Django DATA_UPLOAD_MAX_MEMORY_SIZE, Spring spring.servlet.multipart.max-file-size, ASP.NET MaxRequestBodySize.
3. The layers in front of nginx
- Kubernetes with ingress-nginx — the ingress controller is an nginx too, with its own limit. Set it per Ingress:
metadata: annotations: nginx.ingress.kubernetes.io/proxy-body-size: 50m- A CDN or cloud load balancer — many have a fixed maximum request size on their plans (Cloudflare’s Free and Pro plans, for example, stop at 100 MB). For very large files, upload directly to object storage (S3 presigned URLs and similar) instead of through your server.
To find which layer says 413, look at the response: nginx’s page says nginx at the bottom, other layers answer with their own page or JSON. Check the logs in order — from the outermost layer to your app.
Note
Very large uploads also hit time limits. nginx closes a slow upload after client_body_timeout (60 s between two reads) and waits for the app’s answer up to proxy_read_timeout (60 s). For multi-gigabyte files, direct-to-storage uploads are more reliable than raising every limit.
Shell, we have a problem!
Similar, but different: 414 Request-URI Too Large — the URL itself is too long (huge query strings); raise large_client_header_buffers, or send the data in the body. 400 Request Header Or Cookie Too Large — headers or cookies are too big, same setting. 502 or 504 during an upload — the app crashed or took too long; see Nginx 502 Bad Gateway. For a config that sets this from the start, see the guides for Node.js and WordPress. A 403 is another matter: see Nginx 403.
Found this useful? Share it.
Found a mistake? Let us know at contact@ohsudo.com.