Fix 413 responses when uploading through Nginx
Set a deliberate request-body limit, check application and gateway limits, and test the complete upload rather than only the proxy configuration.
If Nginx generated the 413, inspect client_max_body_size for the matched request. Its default is 1m; the limit covers the entire request body, not just the uploaded file. A 413 can also originate from an earlier gateway or the application.
Set the limit in the appropriate context
For a server that proxies an upload route, for example:
server {
listen 80;
server_name example.com;
client_max_body_size 20M;
location /upload/ {
client_max_body_size 100M;
proxy_pass http://127.0.0.1:8080;
}
}
The directive is valid in http, server, and location. More specific settings override inherited ones. Choose the intended URL boundary: /upload/ and /upload are not identical locations.
sudo nginx -t && sudo systemctl reload nginx
sudo nginx -T
Use the correct instance's binary and startup options. -T reads the current files; confirm the reload succeeded and inspect the selected location before concluding the change is active.
Align limits across the actual upload path
PHP's upload_max_filesize limits a file, while post_max_size limits the POST body. The latter needs room for multipart framing and other fields. They need to support the intended upload; neither must blindly equal every larger Nginx limit.
Express's JSON parser limit does not control multipart middleware. Spring has separate multipart settings. Django's DATA_UPLOAD_MAX_MEMORY_SIZE concerns request data checked by Django and excludes uploaded-file data in its documented calculation; it is not a universal maximum uploaded-file size. Check the upload handler and storage policy actually in use.
CDNs, API gateways, load balancers, and another Nginx hop may impose different limits. Identify the component generating the response using logs and request IDs; a Server header alone is not conclusive. Check current provider limits for your product and target type rather than copying an unscoped size figure.
Test just below and above the intended boundary
Send representative multipart requests and verify the application's response and stored file. Include framing overhead when selecting test sizes. Record request size explicitly if you need it in analysis; a 413 alone cannot reveal the size received. DataKit log collection can retain URI and status evidence once the fields are present and parsed.
For large objects, a presigned object-storage upload can bypass the application proxy path. It still has authorization, object-size, storage-service, and network constraints; it does not remove every limit.
FAQ
Does client_max_body_size 0 mean unlimited uploads?
It disables this Nginx size check. Other layers and resource constraints still apply. Choose it only with an intentional capacity and abuse-control design.
Will a larger body always stay out of memory?
Nginx commonly buffers request bodies and spills beyond its configured buffer to temporary files. Buffering mode and application behavior matter, and concurrent uploads consume resources. Check temporary disk capacity as well as memory.
Why did fixing 413 reveal a timeout?
A larger request may take longer to upload or process. Check the client-body idle timeout and upstream/application deadlines. Adjust the relevant phase deliberately; a size limit and a timeout control different things.
References: Nginx body limit, Django upload settings.
Contact us
Join the community
to join the community
Try Guance
Start online and pay only for what you use.
Get startedChoose a Guance plan