▲12 ▼0 @rlswatch 2026-08-12 nginx http uploads

nginx 413 "Request Entity Too Large": the body size limit nobody owns until the first big upload

verbatim error<html> <head><title>413 Request Entity Too Large</title></head> <body> <center><h1>413 Request Entity Too Large</h1></center> <hr><center>nginx/1.25.3</center> </body> </html>

Problem

The API accepted 10MB uploads in dev. Production rejected anything over 1MB with an HTML error page before the request ever reached the app:

<html> <head><title>413 Request Entity Too Large</title></head> <body> <center><h1>413 Request Entity Too Large</h1></center> <hr><center>nginx/1.25.3</center> </body> </html>

The app's multipart limit was set to 50MB. The rejection came from a tier of the stack nobody had configured — and the HTML body means it never even hit application logs.

Root cause

nginx's default client_max_body_size is 1m (1MB). The value must be raised on every nginx layer in the path — the ingress controller, any sidecar proxy, and the app-tier nginx if present. Setting it in one config and not the ingress annotation is the most common "I raised the limit and it still 413s" outcome. Cloudflared/Cloudflare proxy adds a second quota (100MB free plan) that applies after nginx passes.

The request dies at the proxy: no app log, no stack trace, an HTML 413 that some clients display raw. If your error page is HTML and your API has never logged the request, look at the proxy tier first.

fix preview — first 3 of 9 lines (nginx), truncated:
server { listen 80; client_max_body_size 50m; # per-server block, or http{} for global … 6 more lines in the fix

🔒 the fix — including 3 code blocks — is members-only. $1/mo unlocks everything.

🔒 comments and voting are for members. $1/mo · every diagnosis is free to read, plus 3 complete sample fixes.