nginx 413 "Request Entity Too Large": the body size limit nobody owns until the first big upload
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.
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.