413 Request Entity Too Large
You submitted a form or pushed a file and the server threw it straight back with 413 Request Entity Too Large. Nothing crashed. The server read how big the body was, decided that was more than it would accept, and refused before your application ever saw the request. The fix is a configuration value, and usually two of them.
Updated June 2026 · 9 min read
-
Written by
Andrian Valeanu
Founder of Pulsetic
Andrian Valeanu founded Pulsetic and, before it, Designmodo. Across 15-plus years he has shipped web products, design tools, and monitoring software teams around the world rely on.
-
Reviewed by
Ionut Caval
Technical reviewer
Ionut Caval reviews Pulsetic's technical guides for accuracy. He works hands-on with web servers, networking, and uptime monitoring day to day, and makes sure the causes and fixes here hold up in production.
The short version: The body you sent is bigger than the server will accept. Uploading something? Send a smaller file, or split it across several submissions. Running the server? On nginx, raise client_max_body_size from its 1m default, then raise the matching limit in your application runtime too, because PHP, ASP.NET and Node each enforce one of their own.
Key takeaways
- A
413means the server refused the request because the body was larger than it is willing to read. It usually decides from theContent-Lengthheader alone, before a byte of your file has arrived, which is why a huge upload can fail almost instantly. - The name changed twice. RFC 2616 called it
Request Entity Too Large, RFC 7231 renamed itPayload Too Large, and RFC 9110, the current HTTP specification, calls itContent Too Large. All three describe the same status, and servers still send the older phrases. - On nginx this is nearly always
client_max_body_size, which defaults to1m. nginx rejects the request itself, so your application never runs and never logs it, and there is nothing to debug in the app. - Two limits usually have to move together: the web server's and the application runtime's. Raise
client_max_body_sizebut leave PHP'supload_max_filesizeandpost_max_sizealone and the 413 disappears, replaced by an upload that silently does nothing. - Every hop counts. A CDN, a WAF, a load balancer, and the origin each carry their own body ceiling, and the smallest one wins. Cloudflare caps uploads at 100 MB on Free and Pro no matter how generous your origin config is.
- Error type
- HTTP 4xx client error
- Whose side
- Usually the website config; sometimes what you sent
- Fix difficulty
- Easy to moderate
- Common cause
- Request body exceeds a configured size limit
How did you find out this time?
Pulsetic is website uptime monitoring. It checks your URL from outside your network as often as every 30 seconds, confirms any failure from another region, then emails you.
10 monitors free, email alerts on failure and recovery. No credit card.
What does 413 Request Entity Too Large mean?
A 413 is a client-error response saying the request body was larger than the server is willing or able to process. RFC 9110, the current HTTP specification, names it Content Too Large and adds that the server may terminate the request, or otherwise close the connection. It is a size decision and nothing more. Authentication, routing, permissions, whether the endpoint even exists: none of that gets evaluated, because the server ruled on the Content-Length header and stopped there. That is why a 413 on a 500 MB upload can come back in milliseconds, long before the file has finished going anywhere.
The confusing part is that the refusal happens above your application. A normal request passes through a CDN, then a load balancer or reverse proxy, then the web server, then the runtime holding your code, and every one of those enforces its own body ceiling. Whichever ceiling is smallest answers first, so your code never runs, never logs, and has nothing to show you. Fixing a 413 is therefore a hunt for the layer that owns the smallest number, followed by raising the limit in each layer that would have objected next. RFC 9110 also says a server should send a Retry-After header when the limit is temporary, though in practice most 413s come from a fixed configured value rather than a passing condition.
- 413
- HTTP status code
- 1 MB
- Default nginx request body limit
- 2M / 8M
- PHP upload_max_filesize and post_max_size defaults
- RFC 9110
- Spec that renamed it Content Too Large
How the 413 Request Entity Too Large error appears
The wording changes depending on your browser, device, or server. Here is how this error commonly shows up:
413
Request Entity Too Large
The requested resource does not allow request data with POST requests, or the amount of data provided in the request exceeds the capacity limit.
413 Request Entity Too Large413 Payload Too Large413 Content Too LargeRequest Entity Too Large nginx413 Request Entity Too Large nginxnginx 413HTTP Error 413413 errorHTTP Error 404.13 - CONTENT_LENGTH_TOO_LARGE
413 vs 400, 414 and 431
All four mean the server rejected the shape or the size of your request, but each one points at a different part of it.
| Code | What it means | Who fixes it |
|---|---|---|
| 413 Content Too Large | The request body is bigger than the server will accept. Older specs and most servers still call it Request Entity Too Large or Payload Too Large. | The website owner, by raising the body limit; or the client, by sending less per request. |
| 400 Bad Request | The server could not read the request, so it never got as far as measuring it. Some servers also fall back to 400 for an oversized body when they have no size-specific answer to give. | Whoever built the request, by fixing what is malformed in it. Retrying the same bytes returns the same 400. |
| 414 URI Too Long | The request line is too long, not the body. Typically a query string that should have been sent as a POST body instead. | The client, by shortening the URL; or the owner, by raising the request line and header buffers. |
| 431 Request Header Fields Too Large | The headers, most often the cookies, exceeded what the server will read. The body plays no part in it. | The visitor, by clearing that website's cookies; or the owner, by trimming what the app sets. |
Request body limits by layer, and their defaults
A 413 is one of these settings firing. Find the layer that owns the smallest number and you have found the fix.
| Layer | Setting | Default | Where it goes |
|---|---|---|---|
| nginx | client_max_body_size | 1m | http, server or location block |
| Apache httpd | LimitRequestBody | 0, meaning unlimited | server config, virtual host, directory, .htaccess |
| PHP | upload_max_filesize | 2M | php.ini, or a per-pool or per-vhost override |
| PHP | post_max_size | 8M | php.ini; has to stay above upload_max_filesize |
| IIS request filtering | maxAllowedContentLength | 30000000 bytes, roughly 28.6 MB | requestLimits in web.config or applicationHost.config |
| ASP.NET on .NET Framework | maxRequestLength | 4096 kilobytes, so 4 MB | httpRuntime in web.config |
| ASP.NET Core (Kestrel) | MaxRequestBodySize | 30,000,000 bytes, roughly 28.6 MB | KestrelServerLimits, or overridden per endpoint |
| Cloudflare | Maximum upload size | 100 MB on Free and Pro, 200 MB Business, 500 MB or more Enterprise | Network settings in the Cloudflare dashboard |
Which layer sent the 413, and how to tell
The same status code comes from at least four different places in a normal stack, and each one leaves a different fingerprint.
| Suspect | Telltale sign | How to confirm | Typical fix |
|---|---|---|---|
| nginx | The response body is the bare nginx error page and your application log has no record of the request | Grep the nginx error log for client intended to send too large body | Raise client_max_body_size on the server or location that handles uploads |
| Apache httpd | The response carries Server: Apache and the page names the path that refused the POST | Search the vhost, the Directory blocks, and any .htaccess for LimitRequestBody | Raise the value, or drop the directive to return to the unlimited default |
| PHP or another app runtime | No 413 at all: the form posts, then $_POST and $_FILES come back empty | Compare the body size against upload_max_filesize and post_max_size in phpinfo() | Raise both, keeping post_max_size the larger of the two |
| CDN or WAF | The 413 comes back fast, carries a ray or request ID, and the origin logs show nothing at all | Send the same request straight to the origin IP, bypassing the edge | Raise the edge upload ceiling, chunk the upload, or serve that hostname DNS only |
| IIS request filtering | The page reads HTTP Error 404.13 - CONTENT_LENGTH_TOO_LARGE rather than 413 | Look for the 413.1 substatus in the IIS log | Raise maxAllowedContentLength, and maxRequestLength as well for ASP.NET |
What causes 413 Request Entity Too Large?
- An upload larger than the web server's body limit. On nginx that is
client_max_body_size, and its default of1mcatches more people than any other single setting on this page. - A POST or JSON body over the application framework's own parser limit, which is often far smaller than the web server's. Express and its body parser, for instance, ship a 100 KB default for JSON.
- PHP left at its defaults,
upload_max_filesizeat2Mandpost_max_sizeat8M, while the web server in front of it was raised. - Base64 encoding a file into a JSON body, which adds roughly a third to its size, so a file comfortably under the limit arrives over it.
- Several files submitted through one multipart form, where the limit applies to the whole request body rather than to each file separately.
- A CDN or WAF ceiling sitting in front of the origin. Cloudflare allows 100 MB uploads on its Free and Pro plans regardless of what your own server would have accepted.
- A reverse-proxy chain where only one hop was raised, so the request clears the edge and then dies at the next box along.
- Windows stack defaults: IIS request filtering at
maxAllowedContentLengthof roughly 28.6 MB, or ASP.NET'smaxRequestLengthat 4 MB. - A deliberate API limit, sometimes documented and sometimes not, meant to stop one client posting an enormous payload.
How to find the cause fast
- Confirm the code and find out who sent it. Repeat the request with
curl -sS -D - -o /dev/nulland read both the status line and theServerheader on the 413. - Measure the real body size, not the file size on disk. The browser network panel reports the payload it sent, and
curl -vprints theContent-Lengthon the request line. That number is the one the server judges. - Read the web server error log. nginx writes
client intended to send too large bodyalong with the byte count it saw, which usually settles the question in a single line. - Bypass the edge. Send the same request straight to the origin IP, or to a DNS-only hostname; if it succeeds there, the CDN or WAF owns the limit.
- Check the application runtime last. If the 413 stops but the upload still fails silently, the web server let the body through and the runtime is now the one rejecting it.
How 413 Request Entity Too Large looks from the outside
A 413 is nearly invisible to ordinary monitoring, because triggering it takes a large request body and monitoring checks are small GETs. The homepage stays green, the API health check stays green, and meanwhile every upload on the website fails. The way a 413 arrives makes it worse: the server answers immediately and correctly, so there is no slow response, no timeout, no connection error, nothing that resembles trouble from the outside. The changes that cause one are quiet too. A deploy that overwrites an nginx config, a container image built without your tuned php.ini, or a plan change at the CDN can each reset a limit to its default without anyone touching the upload code. Checking the specific endpoints that matter, and asserting the status code you expect on each, is what turns this into an alert rather than a run of support tickets.
To confirm the exact code a URL returns, or to re-test several at once after a fix, run them through the free bulk URL status checker.
How to fix 413 Request Entity Too Large
If you are uploading a file
- Shrink the file. Compress an image, export the PDF at a lower resolution, or zip a set of documents before sending them.
- Split the upload. Several smaller submissions usually get through where one large one does not, because the limit applies per request.
- Send fewer files per submission. The limit covers the entire request body, so four files attached to one form add together.
- Look for a stated maximum on the page or in the API documentation and stay under it rather than guessing at the ceiling.
- Calling an API? Send the file as a normal multipart upload instead of base64 inside a JSON body, which avoids adding a third to its size.
- If the file is genuinely inside the stated limit, the ceiling is misconfigured. Tell the website owner, and include the file size and the exact time you tried.
If you run the website: the web server and the edge
- On nginx, raise
client_max_body_sizefrom its1mdefault. Scope it to thelocationthat handles uploads where you can, runnginx -t, then reload. - On Apache, find the
LimitRequestBodythat someone set. It defaults to0, meaning unlimited, so a 413 from Apache means it was configured somewhere: a vhost, aDirectoryblock, or an.htaccessfile in the upload path. - On IIS, raise
maxAllowedContentLengthinsiderequestFiltering, in bytes, and remember the request filtering block can live inapplicationHost.configas well as in yourweb.config. - Raise the limit at every hop the request passes through. A load balancer, a reverse proxy, and the origin each enforce their own, and the smallest one decides.
- Check the CDN or WAF ceiling. On Cloudflare that is the maximum upload size for your plan, and a zone administrator can lower it from the Network settings.
- Keep the new limit deliberate rather than unlimited.
client_max_body_size 0does switch the check off, and it also hands anyone on the internet a way to fill your disk.
If you run the website: the application runtime
- For PHP, raise
upload_max_filesizeandpost_max_sizetogether, keepingpost_max_sizethe larger value because the body carries the file plus every other form field. - Keep
memory_limitabovepost_max_size, as the PHP manual recommends, so a large upload does not fail on memory instead. - Restart PHP-FPM after editing, then confirm with
phpinfo()orphp -ithat the values you changed are the ones in effect. A per-pool or per-vhost override quietly beats the globalphp.ini. - On ASP.NET, set
maxRequestLengthinhttpRuntime, measured in kilobytes, alongside the byte value inmaxAllowedContentLength. On ASP.NET Core, set the KestrelMaxRequestBodySize, or override it for the single endpoint that needs it. - On Node, Express and similar frameworks, raise the body parser limit only on the routes that accept uploads rather than across the whole app.
- For anything past roughly 100 MB, move to chunked or resumable uploads, or hand the browser a presigned URL so the file goes straight to object storage and never touches your web server.
Still not fixed? Next steps
- Reproduce it with
curland read theServerheader on the 413 itself. That names the box in the chain that refused you, and it is often not the one you have been editing. - Measure what actually goes on the wire. Multipart forms wrap every field in boundary markers, several files in one submission add together, and base64 encoding inflates a payload by roughly a third, so a 45 MB file can arrive as a 60 MB body and trip a 50 MB limit.
- Walk the chain from the edge inward: CDN or WAF, then the load balancer, then the web server, then the application runtime. Raise the limit at every hop, because the smallest number in the chain is the one that decides.
- If uploads regularly run to tens or hundreds of megabytes, stop raising ceilings and change the shape of the upload. Chunked or resumable uploads, or a presigned URL that sends the file straight to object storage, keep the large body away from your web server entirely.
Code & configuration
Copy-paste starting points. Replace example.com and the paths with your own, and test changes on staging before production.
nginx: raise client_max_body_size where the uploads land
# The default is 1m, and it applies to http, server and location blocks.
# The innermost matching value wins, so scope it as tightly as you can.
http {
client_max_body_size 1m; # site-wide default stays small
server {
server_name example.com;
location /upload/ {
client_max_body_size 64m; # this path only
proxy_pass http://app_backend;
}
}
}
# client_max_body_size 0; disables the check entirely. Avoid that on
# anything public: it lets a stranger send a body of any size.
#
# Apply with: nginx -t && nginx -s reload
PHP: both values must move, and post_max_size must be the larger one
; php.ini defaults are upload_max_filesize = 2M and post_max_size = 8M.
; post_max_size covers the WHOLE body: the file plus every other form
; field plus multipart boundaries, so leave it comfortably above
; upload_max_filesize or large uploads still fail.
upload_max_filesize = 64M
post_max_size = 72M
memory_limit = 256M ; the PHP manual: keep this above post_max_size
max_file_uploads = 20
; If post_max_size is exceeded, PHP does NOT send a 413:
; $_POST and $_FILES simply arrive empty. That silent failure is the
; usual sign the web server limit was raised and this one was not.
; Verify what is actually loaded, then restart the pool:
; php -i | grep -E 'upload_max_filesize|post_max_size|memory_limit'
; systemctl restart php-fpm
Reproduce a 413 with curl and a large body
# Build a 5 MB test file (portable across macOS and Linux)
dd if=/dev/zero of=/tmp/big.bin bs=1024 count=5120
# POST it and print the status code only
curl -sS -o /dev/null -w '%{http_code}\n' \
-F 'file=@/tmp/big.bin' https://example.com/upload
# 413
# Same request with the response headers, to see WHICH server refused it
curl -sS -D - -o /dev/null -F 'file=@/tmp/big.bin' https://example.com/upload
# HTTP/1.1 413 Request Entity Too Large
# Server: nginx
# Connection: close
# nginx compares Content-Length against the limit before reading the body,
# so the 413 comes back almost immediately. Over HTTP/1.1 curl also adds an
# Expect: 100-continue header for a body this size, which lets the server
# refuse it without the 5 MB ever leaving your machine.
IIS and ASP.NET: two limits, two different units
<configuration>
<system.web>
<!-- ASP.NET on .NET Framework. KILOBYTES. Default 4096 (4 MB). -->
<httpRuntime maxRequestLength="102400" />
</system.web>
<system.webServer>
<security>
<requestFiltering>
<!-- IIS request filtering. BYTES. Default 30000000 (about 28.6 MB). -->
<requestLimits maxAllowedContentLength="104857600" />
</requestFiltering>
</security>
</system.webServer>
</configuration>
<!-- 102400 KB and 104857600 bytes are both 100 MB. Raise only one of them
and the lower ceiling still decides. When request filtering blocks the
body, IIS shows HTTP Error 404.13 CONTENT_LENGTH_TOO_LARGE and logs the
413.1 substatus, so the visible error says Not Found. -->
How to prevent 413 Request Entity Too Large
A 413 rarely shows up on the homepage, and that is what makes it easy to miss: the website looks perfectly healthy while every upload quietly fails after a deploy overwrites a config or a container ships without your tuned limits. Pulsetic checks the URLs you choose from multiple locations every 30 seconds and alerts you by email, SMS, voice call, Slack, Discord or webhook when one stops returning the status you expect. It measures availability from outside your infrastructure, so it can tell you an endpoint is answering 413; it cannot read your nginx config or your PHP settings for you.
Learn how Pulsetic's uptime monitoring detects this from the outside, across 15+ locations.
Frequently asked questions
-
What does 413 Request Entity Too Large mean?
The server looked at the size of the request body you were sending, decided it was more than it is willing or able to process, and refused to handle it. Almost always that body is a file upload or a large POST. The server itself is healthy: this is a configured ceiling doing exactly what it was set up to do, not a crash and not an outage.
-
How do I fix 413 Request Entity Too Large in nginx?
Raise
client_max_body_size, which defaults to1m. Put it in thelocationblock that handles uploads if you can, or theserverblock, orhttpto cover everything. Set it above the largest body you genuinely expect, runnginx -tto test the config, then reload withnginx -s reload. Setting it to0turns the check off completely, which is worth avoiding on anything public. -
What is the equivalent fix on Apache?
Apache uses
LimitRequestBody, measured in bytes. It defaults to0, meaning unlimited, so a 413 from Apache tells you somebody configured it: check the vhost, theDirectoryblocks, and any.htaccessin the upload path, since the directive is allowed in all of them. Raise the value or remove the directive. The documented ceiling is 2147483647 bytes, so 2 GB is the most this setting will accept. -
Why did my upload fail even though the file is under the limit?
The body on the wire is bigger than the file on disk. Multipart form data wraps every field in boundary markers, several files in one form add together, and base64 encoding, which is how files usually travel inside JSON, inflates the size by about a third. A 40 MB file sent as base64 JSON arrives as roughly 54 MB. Size your limits against the request body, not against the file.
-
Why do I have to raise two settings for a PHP upload?
The web server and the language runtime each police the body independently. nginx or Apache decides whether the request is even allowed in, and PHP then decides whether it will parse it, using
upload_max_filesizefor the file andpost_max_sizefor the whole POST. Raise only the web server and the 413 goes away but the upload still fails, this time in silence, with$_POSTand$_FILESempty.post_max_sizehas to be the larger of the two PHP values. -
Which IIS setting is in bytes and which is in kilobytes?
The IIS request filtering setting
maxAllowedContentLengthis in bytes and defaults to30000000, about 28.6 MB. The ASP.NET settingmaxRequestLengthinhttpRuntimeis in kilobytes and defaults to4096, which is 4 MB. Mixing up the units is the classic mistake here: a 100 MB ceiling meansmaxAllowedContentLength="104857600"andmaxRequestLength="102400". Raise only one and the lower ceiling still wins. -
Why does IIS show a 404.13 error instead of a 413?
When request filtering blocks an oversized body, IIS returns a 404 to the browser with substatus 13 and the text CONTENT_LENGTH_TOO_LARGE, while logging the event under the 413.1 substatus. So the page a visitor sees says Not Found, and the real cause is a size limit. Raise
maxAllowedContentLengthinweb.configorapplicationHost.configand the upload goes through. -
Can an uptime monitor catch a 413?
Only if it checks the request that triggers one. A 413 fires on a large request body, so a monitor running plain GET checks against the homepage will report everything healthy while every upload on the website fails. Watch the endpoints that matter and assert the status code you expect on each, so a config change that quietly drops a limit back to its default surfaces as a failed check rather than as support tickets.
-
Why does raising client_max_body_size alone not fix my PHP upload?
Because you moved one gate of two. nginx now lets the body through and PHP takes over: if the file is bigger than
upload_max_filesizeit lands in$_FILEScarrying the error codeUPLOAD_ERR_INI_SIZE, and if the whole POST is bigger thanpost_max_sizethen$_POSTand$_FILEScome back completely empty. Neither case produces a 413, which is exactly what makes it confusing. Raise both, restart PHP-FPM, then checkphpinfo()to confirm the values you edited are the ones actually loaded, since a per-pool or per-vhost override quietly beats the globalphp.ini. -
Is 413 Request Entity Too Large the same as 413 Payload Too Large?
Same status code, three names across the specs. RFC 2616 introduced it as Request Entity Too Large, RFC 7231 renamed it Payload Too Large, and RFC 9110, the current HTTP specification, calls it Content Too Large. nginx still prints Request Entity Too Large on its error page, so the oldest wording is the one most people see in the wild. The behaviour is identical in every case: the server is refusing a body it considers too big.
-
Why does the browser show a network error instead of the 413 page?
When a server rejects a body it has not finished reading, it often stops the transfer and closes the connection rather than swallowing the remaining megabytes. The client is still uploading at that moment, so it reports a reset or a generic network failure and never renders the 413 body. The nginx documentation warns about this directly, noting that browsers cannot display this error correctly. Repeat the request with
curland the real status code shows up. -
Can Cloudflare return a 413 even though my origin would accept the upload?
Yes, and it is common. Cloudflare enforces its own maximum upload size before the request reaches you: 100 MB on Free and Pro, 200 MB on Business, and 500 MB or more on Enterprise, and a zone administrator can lower that figure from the Network settings. So an origin happily configured for 300 MB files still gets nothing, because the edge answered 413 and your origin logs stay empty. The options are to split the upload into chunks, serve that hostname DNS only so it bypasses the proxy, or ask Cloudflare about a higher limit.
-
Should an API return 413 or 400 for a body that is too big?
Return 413. It states the specific reason, so a client can react sensibly by splitting the payload instead of guessing at what it got wrong. A 400 Bad Request says only that the server could not parse the request, which sends developers hunting for a syntax problem that is not there. Publish the maximum size in your API documentation as well, and if the limit is temporary, RFC 9110 says to add a
Retry-Afterheader so clients know the rejection will not last.
Trusted by teams at companies around the world
-
Catch the next outage before your visitors do.
2-minute setup · Cancel any time
-
No credit card needed