413 Request Entity Too Large
nginx
Nginx limits the size of a request body — file uploads, large form posts, API payloads — with the client_max_body_size directive. The default is just 1 MB, so the first time someone uploads a photo or a PDF to your app, they hit this error.
The fix
Set client_max_body_size to what your application needs:
server {
server_name example.com;
client_max_body_size 64M;
# …
}
sudo nginx -t && sudo systemctl reload nginx
Where to put it
The directive is valid in three contexts, and the most specific one wins:
http {
client_max_body_size 16M; # default for all sites
server {
client_max_body_size 64M; # this site
location /api/upload {
client_max_body_size 512M; # this endpoint only
}
}
}
Raising the limit only where uploads happen is the most secure approach: large bodies tie up connections and disk space for temporary files, so you don’t want every URL to accept 512 MB.
client_max_body_size 0; disables the check entirely — avoid it on public sites.
Then fix the next limit in the chain
Nginx is often only the first gatekeeper. After raising it, the request may fail further along:
PHP
upload_max_filesize = 64M
post_max_size = 64M
Put these in a file under /etc/php/8.3/fpm/conf.d/ and restart PHP-FPM. For WordPress specifics, see increase the WordPress upload size.
Node.js (Express)
app.use(express.json({ limit: '10mb' }));
app.use(express.urlencoded({ limit: '10mb', extended: true }));
Upload libraries like multer have their own limits.fileSize.
Python
Django: DATA_UPLOAD_MAX_MEMORY_SIZE and FILE_UPLOAD_MAX_MEMORY_SIZE. Flask: MAX_CONTENT_LENGTH.
Other proxies in front
- Another Nginx (for example Nginx Proxy Manager or an ingress controller) — set the limit there too. In Nginx Proxy Manager, add
client_max_body_size 64M;in the proxy host’s Advanced tab. - Cloudflare — the free and Pro plans accept request bodies up to 100 MB. Larger uploads must bypass the proxy (a DNS-only subdomain) or use chunked uploads.
- Kubernetes ingress-nginx — annotation
nginx.ingress.kubernetes.io/proxy-body-size: "64m".
Nginx inside Docker
If Nginx runs in a container, edit the config file you mount into it (or add a conf.d snippet), then reload inside the container:
docker exec nginx nginx -t && docker exec nginx nginx -s reload
Large uploads: related settings
For uploads in the hundreds of megabytes, a few more directives help:
location /upload {
client_max_body_size 1G;
client_body_timeout 300s; # time between two reads of the body
proxy_request_buffering off; # stream to the upstream instead of buffering to disk first
proxy_read_timeout 300s;
proxy_pass http://127.0.0.1:3000;
}
By default, Nginx buffers the whole body to a temporary file (client_body_temp_path) before passing it on — make sure that location has enough disk space, or disable request buffering for streaming uploads.
How to confirm which layer rejects the request
- The 413 page says nginx → Nginx limit.
- A JSON error or app-styled page → the application’s limit.
- WordPress shows “exceeds the upload_max_filesize directive” → PHP limit.
- Cloudflare-branded 413 → Cloudflare’s limit.
Test with curl and a dummy file:
head -c 20M /dev/urandom > test.bin
curl -s -o /dev/null -w "%{http_code}\n" -F "[email protected]" https://example.com/upload
Sensible values
| Use case | Suggested limit |
|---|---|
| APIs with JSON bodies | 1–10 MB |
| Blogs, CMS with images | 32–64 MB |
| Document uploads, podcasts | 128–256 MB |
| Video, backups, file sharing (Nextcloud) | 1–16 GB, on specific locations |
Related: Nginx location blocks for scoping the limit, and installing Nginx on Ubuntu.