How HTTP Works
4xx · Client error
< HTTP/1.1 413 Content Too Large

413 Payload Too Large (Content Too Large): Causes and Fixes

413 Content Too Large (formerly Payload Too Large): find which layer rejected the upload and raise the limit in nginx, Apache, Cloudflare, Express and more.

Reviewed 4 min readbeginner5 sourcesTry itMarkdown
Cacheable
Only with explicit freshness
Retry?
No: send a smaller body
Usually sent by
Reverse proxy, CDN or origin
Spec
RFC 9110 §15.5.14
Often confused with
414
On this page

TL;DR: Some layer between the client and your app (nginx, a CDN, an API gateway or the framework’s body parser) rejected the body for being over its size cap. Find which layer answered, then raise the limit there, or send the file by another route such as chunking or a presigned URL.

What it means

The request was syntactically fine, but its body (the “content” in RFC 9110 terms) exceeded what the server will accept. The server may close the connection to stop the client from sending the rest. Because every hop has its own default limit, raising the limit in one place often just moves the 413 to the next hop.

HTTP/1.1 413 Request Entity Too Large
Server: nginx/1.25.5
Content-Type: text/html
Content-Length: 183
Connection: close

nginx still emits the pre-RFC 9110 phrase, and its error log says exactly what happened:

2026/10/04 09:12:41 [error] 31#31: *874 client intended to send too large body: 5242880 bytes, client: 203.0.113.9, server: example.com, request: "POST /upload HTTP/1.1", host: "example.com"

Who sent it?

SignalLikely sender
Server: nginx and the log line abovenginx (or ingress-nginx in Kubernetes)
Server: cloudflare plus CF-RayCloudflare, plan limit exceeded
{"message":"Request Entity Too Large"} with an x-amzn-ErrorType headerAPI Gateway
PayloadTooLargeError: request entity too large in the app logExpress body-parser / express.json()
FUNCTION_PAYLOAD_TOO_LARGE in the body, X-Vercel-Error headerVercel (4.5 MB request cap on functions)
Plain Request Entity Too Large page, Server: ApacheApache LimitRequestBody, or PHP limits

Reproduce and see who answers. curl sends Expect: 100-continue for large POST bodies on HTTP/1.1, and nginx answers 413 before the body is uploaded, which is the fast way to confirm:

head -c 5M /dev/zero > big.bin
curl -sv -o /dev/null -X POST --data-binary @big.bin https://example.com/upload 2>&1 | grep -iE '^[<>] (POST|HTTP|server|cf-ray|via|expect)'

Fix it by stack

nginx

Default is 1m. Set it where the request lands (http, server or location), then nginx -t && nginx -s reload:

server {
    client_max_body_size 50m;

    location /upload {
        client_max_body_size 500m;
        proxy_request_buffering off;   # stream to the upstream instead of buffering to disk
        proxy_pass http://app;
    }
}

client_max_body_size 0; disables the check entirely, which is rarely what you want on a public endpoint.

ingress-nginx (Kubernetes)

The ingress controller enforces its own limit before traffic reaches your pod. Per Ingress:

metadata:
  annotations:
    nginx.ingress.kubernetes.io/proxy-body-size: "50m"

Or cluster-wide with proxy-body-size in the controller ConfigMap. If you also run nginx inside the pod, raise that one too.

Apache and PHP

LimitRequestBody defaults to 0 (unlimited); the maximum is 2147483647. If you did not set it, the cap is probably PHP’s:

LimitRequestBody 52428800
; php.ini: post_max_size must be >= upload_max_filesize
upload_max_filesize = 50M
post_max_size = 55M

Express, Node and Go

express.json() and express.urlencoded() default to 100kb. The error is PayloadTooLargeError: request entity too large with err.status === 413:

app.use(express.json({ limit: '2mb' }))

For file uploads use a streaming parser (multer with limits.fileSize, busboy) instead of raising the JSON limit. In Go, wrap the body with http.MaxBytesReader(w, r.Body, 10<<20); reads past the limit fail with http: request body too large and you choose the status code.

Next.js, Vercel, Django

  • Next.js Pages Router API routes: export const config = { api: { bodyParser: { sizeLimit: '4mb' } } }. Server Actions default to 1 MB and are raised with serverActions.bodySizeLimit in next.config.
  • Vercel functions reject request bodies over 4.5 MB regardless of your code. Upload directly to blob storage with a presigned or client-upload token.
  • Django enforces DATA_UPLOAD_MAX_MEMORY_SIZE (2.5 MB, file parts excluded) and raises RequestDataTooBig, which Django turns into a 400, not a 413.

Cloudflare and cloud gateways

  • Cloudflare proxy: 100 MB (Free, Pro), 200 MB (Business), 500 MB (Enterprise) by default. A DNS-only (grey cloud) record bypasses it.
  • API Gateway: 10 MB payload limit. Lambda synchronous invocation payloads cap at 6 MB, and an ALB with a Lambda target at 1 MB.
  • ALB to an instance or container target: the ALB does not impose a body size limit, so a 413 behind an ALB comes from your own stack.

For anything above a few MB, upload straight to object storage (S3 presigned PUT or multipart, GCS resumable) and send only the object key to your API.

Frequently asked questions

What does 413 Content Too Large mean?

The server, or a proxy in front of it, refused the request because the body is larger than it is willing to process. RFC 9110 renamed the code from "Payload Too Large" (and the older "Request Entity Too Large") to "Content Too Large"; the number did not change, and nginx still prints the old text.

How do I fix nginx 413 Request Entity Too Large?

Set client_max_body_size in the http, server or location block, for example client_max_body_size 50m;, then run nginx -t and reload. The default is 1m. If nginx sits behind another proxy or in Kubernetes, that layer has its own limit too.

What is the upload limit for Cloudflare?

Cloudflare accepts request bodies up to 100 MB on Free and Pro, 200 MB on Business and 500 MB on Enterprise by default. Larger uploads must bypass the proxy, use chunked or multipart upload to object storage, or use a presigned URL.

Does Apache LimitRequestBody default to 2 GB?

No. LimitRequestBody defaults to 0, which means unlimited. 2147483647 bytes (2 GB) is the maximum value you can set. If Apache returns 413, someone configured the directive, or PHP (upload_max_filesize, post_max_size) rejected the file instead.

Should a 413 response include Retry-After?

Only if the limit is temporary, for example a quota that resets. RFC 9110 says a server that knows the condition is temporary should send Retry-After. For a fixed size cap the client must send less data, not wait.

Sources

  1. MDN Web Docs: 413 Content Too Largedeveloper.mozilla.org
  2. RFC 9110 Section 15.5.14: 413 Content Too Largerfc-editor.org
  3. nginx: client_max_body_sizenginx.org
  4. Cloudflare: Error 413developers.cloudflare.com
  5. ingress-nginx: proxy-body-size annotationkubernetes.github.io

Keep going

Browse /search