Introduction

When users attempt to upload files larger than Nginx's client_max_body_size limit (default 1MB), Nginx immediately rejects the request with a 413 Request Entity Too Large error. The Nginx error log records:

bash
2026/04/08 17:10:45 [error] 4567#0: *3456 client intended to send too large body: 52428800 bytes, client: 192.168.1.100, server: example.com, request: "POST /upload HTTP/1.1", host: "example.com"

This is one of the most common issues when setting up file upload functionality.

Symptoms

  • Browser immediately returns HTTP 413 Request Entity Too Large
  • Upload fails before reaching the application backend
  • Nginx error log shows "client intended to send too large body" with the byte count
  • The error appears only for larger files; small uploads succeed
  • Application logs show no record of the request since Nginx blocks it

Common Causes

  • Default client_max_body_size of 1MB is too small for file uploads
  • Setting is defined only in the http block and overridden in a server or location block
  • Backend application (PHP, Node.js, Python) has its own upload size limit that also needs adjustment
  • Proxy buffer settings are insufficient for large request bodies being forwarded to upstream

Step-by-Step Fix

  1. 1.Increase client_max_body_size in the appropriate Nginx context. For a server-wide change, edit /etc/nginx/nginx.conf:
  2. 2.```nginx
  3. 3.http {
  4. 4.client_max_body_size 100m;
  5. 5.}
  6. 6.`
  7. 7.Or set it per-location for specific upload endpoints:
  8. 8.```nginx
  9. 9.server {
  10. 10.location /upload {
  11. 11.client_max_body_size 500m;
  12. 12.client_body_timeout 120s;
  13. 13.proxy_pass http://127.0.0.1:3000;
  14. 14.}

location / { client_max_body_size 10m; } } ```

  1. 1.Align backend application limits. For PHP-FPM in php.ini:
  2. 2.```ini
  3. 3.upload_max_filesize = 500M
  4. 4.post_max_size = 520M
  5. 5.`
  6. 6.For Node.js with Express using body-parser or multer, ensure the limit matches:
  7. 7.```javascript
  8. 8.const multer = require('multer');
  9. 9.const upload = multer({ limits: { fileSize: 500 * 1024 * 1024 } });
  10. 10.`
  11. 11.Configure proxy buffer settings if proxying to an upstream:
  12. 12.```nginx
  13. 13.location /upload {
  14. 14.proxy_pass http://127.0.0.1:3000;
  15. 15.proxy_request_buffering on;
  16. 16.client_max_body_size 500m;
  17. 17.proxy_read_timeout 300s;
  18. 18.proxy_send_timeout 300s;
  19. 19.}
  20. 20.`
  21. 21.Add client-side upload timeout to prevent premature connection drops:
  22. 22.```nginx
  23. 23.client_body_timeout 120s;
  24. 24.`
  25. 25.This gives large uploads sufficient time to complete before Nginx closes the connection.
  26. 26.Test and reload:
  27. 27.```bash
  28. 28.sudo nginx -t && sudo systemctl reload nginx
  29. 29.`
  30. 30.Verify with a test upload:
  31. 31.```bash
  32. 32.curl -X POST -F "file=@/tmp/testfile_100mb.bin" https://example.com/upload -v 2>&1 | grep "< HTTP"
  33. 33.`
  34. 34.A successful upload returns HTTP/2 200 or HTTP/1.1 200 OK.

Prevention

  • Document upload size limits in both Nginx and application configuration
  • Add monitoring for 413 response codes in Nginx access logs: awk '$9 == "413"' /var/log/nginx/access.log
  • Implement client-side file size validation before upload to provide immediate user feedback
  • Consider using chunked upload (tus protocol) for very large files to avoid single-request size limits
  • Use a dedicated file storage service (S3, Cloudinary) for uploads to offload bandwidth from the web server