Skip to content
ohsudo, Home
Networking

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.

Beginner3 min readApplies to nginx · PHP-FPM · Node.js / Express · ingress-nginx · Ubuntu · Debian · RHEL / Rocky / AlmaLinux

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 Large
nginx

nginx 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.

  1. Browser upload15 MB file
  2. nginxclient_max_body_size: 1 MB(breaks here)
  3. Your appits own limit comes next
nginx rejects request bodies over client_max_body_size, 1 MB by default, before your app sees them. Every layer between the browser and your code may have its own limit.

TL;DR

server {
# …
client_max_body_size 50m;
}
Terminal window
sudo nginx -t && sudo systemctl reload nginx

1. 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 server block, for the whole site;
  • or only in the location that 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:

Terminal window
sudo nginx -t && sudo systemctl reload nginx

If 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 = 50M
post_max_size = 55M

Then 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.

Tools

Try it yourself

Articles

Related articles