HTTP 413 Content Too Large
413 is the server refusing a request body that's too big. RFC 9110 renamed it Content Too Large. Older specs called it Payload Too Large and Request Entity Too Large, and nginx's error page still says 413 Request Entity Too Large.
413 Content Too Large
The request content is larger than the server is willing or able to process.
Who fixes it: Server config. Technically the client sent too much, but most 413s come from a default limit nobody adjusted. The fix is a config change, or a different upload design.
What 413 means
The server may close the connection to stop the client sending more. If the condition is temporary, it may send Retry-After.
Limits exist at every layer (CDN, load balancer, reverse proxy, framework body parser, serverless platform) and the smallest one wins. Raising the limit in your app does nothing if nginx in front still uses its 1 MB default.
Source: RFC 9110 §15.5.14.
Common causes
- nginx
client_max_body_sizedefaults to1m. Larger uploads get a 413 before your app sees them, and the error log saysclient intended to send too large body. - Express:
express.json()andexpress.urlencoded()default to a100kblimit and throwPayloadTooLargeError: request entity too large(typeentity.too.large). - Vercel Functions: request bodies over 4.5 MB fail with
413: FUNCTION_PAYLOAD_TOO_LARGE. - Next.js Server Actions: request bodies are limited to 1 MB by default.
- Cloudflare: request bodies over 100 MB on the Free and Pro plans (larger on Business and Enterprise).
- Base64-encoding files inside JSON inflates them by about a third, so a 3.5 MB image becomes a body of roughly 4.7 MB.
- In the browser, a 413 from nginx often shows up as a CORS error, because nginx's built-in error page doesn't have your
Access-Control-Allow-Originheader.
How to fix a 413
nginx
Set it in http, server or location, then reload. Scope large limits to the upload endpoint rather than the whole site. Add CORS headers with always so they're present on error responses too.
http {
client_max_body_size 25m; # default 1m; 0 disables the check
}
location /api/upload {
client_max_body_size 100m;
proxy_request_buffering off; # stream large uploads to the app
add_header Access-Control-Allow-Origin https://app.example.com always;
proxy_pass http://127.0.0.1:3000;
}Express
Raise the body parser limit, ideally only on the routes that need it.
app.use(express.json({ limit: '10mb' }));
app.use(express.urlencoded({ extended: true, limit: '10mb' }));Next.js and Vercel
Server Actions have their own limit in next.config. Vercel's 4.5 MB function body limit can't be raised: upload large files straight from the browser to object storage (S3, R2, Vercel Blob) with a presigned URL, and send only the file key to your function.
// next.config.ts
const nextConfig = {
experimental: {
serverActions: { bodySizeLimit: '5mb' },
},
};
export default nextConfig;Test the limit with curl
Generate a file just above the limit and post it. --data-binary sends it byte for byte.
head -c 5242880 /dev/urandom > /tmp/5mb.bin # 5 MB
curl -i https://example.com/api/upload \
-H 'Content-Type: application/octet-stream' \
--data-binary @/tmp/5mb.binHeaders that matter with 413
- Content-Length
- Servers can reject an oversized request from this header alone, before reading the body.
- Retry-After
- Optional. Only meaningful if the limit is temporary, e.g. a quota that resets.
- Expect: 100-continue
- Lets a client send headers first and the body only if the server agrees, so a 413 arrives before a large upload is wasted.
413 vs similar status codes
- 400 Bad Request: nginx returns 400 (not 413) when headers or cookies are too large.
- 431 Request Header Fields Too Large: The precise code for oversized headers rather than an oversized body.
- 414 URI Too Long: The URL itself is too long, usually a huge query string. Move the data into a POST body.
Related status codes
400Bad Request
The server can't or won't process the request because of something it considers a client error.
502Bad Gateway
A gateway or proxy received an invalid response from the upstream server it contacted.
504Gateway Timeout
A gateway or proxy didn't receive a timely response from the upstream server.
Looking for another code? Search the full HTTP status codes list, or read which code your API should return in the REST API status codes guide.
Learn more
HTTP Status Codes for REST APIs: 200 vs 201 vs 204, 400 vs 422 vs 429
A practical guide to choosing the right HTTP status code in REST API design. Covers the most confusing pairs: 200 vs 201, 400 vs 422, 401 vs 403, and when to use 503 vs 429.
REST API Design Best Practices: A Practical Guide
The conventions that make REST APIs intuitive and consistent. Covers URL design, HTTP methods, status codes, versioning, pagination, and error responses.
CORS Explained: Why It Happens and How to Fix It
CORS errors happen when a browser blocks a request to a different origin. Learn how the Same-Origin Policy works, what preflight requests are, and how to configure CORS correctly in Express, FastAPI, and Nginx.
Frequently Asked Questions
What is the difference between 413 Payload Too Large and 413 Content Too Large?▾
Same code, different names. RFC 2616 called it Request Entity Too Large, RFC 7231 Payload Too Large, and RFC 9110 (2022) renamed it Content Too Large. Clients should only look at the number.
How do I fix 413 Request Entity Too Large in nginx?▾
Raise client_max_body_size in the http, server or location block, for example client_max_body_size 25m;, then reload nginx. Also raise the limit in your app framework and in any CDN or load balancer in front, because the lowest limit wins.
Why do I get a CORS error instead of a 413?▾
nginx rejected the upload before your app ran, so your app's CORS headers were never added. The browser sees a response without Access-Control-Allow-Origin and reports a CORS failure. Add the CORS header in nginx with the always flag, or fix the size limit.