ERROR · 19 · VERIFIED 2026-10allwpcare.com/errors/413-request-entity-too-large/
Errors / 413-request-entity-too-large

413 Request Entity Too Large in WordPress

A 413 means your web server refused the upload before WordPress read it. Raise nginx client_max_body_size or Apache LimitRequestBody, then PHP's limits.

The message you see
1−413 Request Entity Too Large
Last verified Oct 2026Tested with WordPress 7.1Applies to WordPress 7.1 (tested on Apache 2.4.69 with mod_php, and nginx 1.31.8 in front of it) · PHP 7.4+

Why it happens

  • nginx refused the request because its body is bigger than client_max_body_size. The default is 1 MB, so a photo or a plugin zip over 1 MB is enough. The nginx error log says client intended to send too large body.
  • Apache refused it because of a LimitRequestBody line in .htaccess, the virtual host or the server config. Apache's own default is 1 GiB (2.4.54 and later), so a small limit means someone set it.
  • Two web servers are stacked, for example nginx in front of Apache, and one of them still has a low limit after you raised the other.
  • The limit sits in a proxy, a firewall or a CDN (a service between visitors and your server) that you cannot see from WordPress. I could not test those. The page text names who answered.

How to fix it

Try the fixes in this order. Each one is independent: stop as soon as the error is gone.

FIX 01

Find out which server said no

  1. Read the words on the error page. Apache's page says "The requested resource does not allow request data with POST requests, or the amount of data provided in the request exceeds the capacity limit." and ends with a line such as Apache/2.4.69 (Debian) Server at …. nginx's page is a plain "413 Request Entity Too Large" with nginx/1.31.8 under a line.
  2. If you only see a red banner or a stuck progress bar, open your browser's developer tools, go to Network, upload again and click the red request. Its status reads 413. The page text is under Response.
  3. Do not trust the Server header alone when two servers are stacked. With nginx in front of Apache and only Apache's limit low, the header said nginx but the page said Apache/2.4.69. Go by the page text.
  4. If you use a host's control panel, the log is under Logs or Errors. nginx writes client intended to send too large body: 2081447 bytes.
FIX 02

nginx: raise client_max_body_size

  1. Open the nginx site file (often /etc/nginx/sites-enabled/yoursite.conf or /etc/nginx/nginx.conf) and add or change client_max_body_size 64m; inside the server { } block. It is also allowed in http { } and location { }. Choose a size a little above your biggest file.
  2. Run sudo nginx -t to check the file, then sudo nginx -s reload to apply it. Nothing changes until the reload.
  3. I tested 1m (the default), 64m and 0 on the same 2.1 MB photo. With 1m it returned 413. With 64m it went through. 0 also let it through, because nginx's documentation says 0 "disables checking of client request body size". Do not use 0 on a live site.
  4. On managed hosting where you cannot edit nginx, ask support to raise it. Tell them the time of the error and that your log says client intended to send too large body.
FIX 03

Apache: raise or remove LimitRequestBody

  1. Search for the directive. In the WordPress folder: grep -n LimitRequestBody .htaccess. Then look in the virtual host and Apache config, usually under /etc/apache2/ or /etc/httpd/.
  2. Change the number (it is in bytes) to a size above your biggest file, for example LimitRequestBody 67108864 for 64 MB. Or delete the line. Apache's default is 1073741824 (1 GiB); in 2.4.53 and earlier it was 0, which means no limit.
  3. I tested it with the line set to 1048576 (1 MB): a 2.1 MB upload returned 413. At 67108864 the same file uploaded. With LimitRequestBody 0 and with the line removed, a request of the same size returned 200.
  4. A .htaccess change applies on the next request. A change in the server or virtual host config needs sudo apachectl graceful (or your host's restart button).
FIX 04

Raise the limit on every server in the chain

  1. If a 413 stays after you raised one limit, a second server in front of or behind it has its own. Typical chains are nginx in front of Apache, or a host's proxy in front of nginx.
  2. I tested nginx in front of the lab's Apache with every pair. Only when both allowed the file did it go through. See the table "Two servers in a row" below.
  3. Change one limit at a time and repeat the upload after each. The page text in the 413 tells you which one you have just fixed.
FIX 05

Then raise PHP's two limits

  1. Getting past the web server only moves the upload to the next gate. PHP checks post_max_size (the whole request) and upload_max_filesize (the file). Set both to the same size in your host's panel or .htaccess on Apache with mod_php. The file exceeds the maximum upload size page shows the methods that work and the ones that are ignored.
  2. I measured each gate with one 2.1 MB photo. See the table "Each gate answers differently". Only when all three allow the file does it save.
FIX 06

Check the result in the same place that failed

  1. Upload the same file again. On Media → Add New the red banner should be gone and the row should turn into a thumbnail.
  2. If the message changes to "The link you followed has expired.", the web server now lets the file in and PHP's post_max_size is too low. See the link you followed has expired.
  3. If it changes to "The uploaded file exceeds the upload_max_filesize directive in php.ini.", see that error.

A 413 means the web server refused the upload because the request was bigger than its limit. It does this before WordPress can read the file, so WordPress has no message of its own for it. The limit is client_max_body_size on nginx (1 MB by default) or LimitRequestBody on Apache. Raise it, reload the server, and then check that PHP's two limits are high enough.

What you see#

It depends on how you upload. The classic form, such as Plugins → Add New → Upload Plugin, shows the server's page. The uploaders on Media → Add New and in the block editor have no 413 text to show, and display their own words.

Where you uploadWhat you see
Plugins → Add New → Upload Plugin, themes, importers (normal form)A full page: "Request Entity Too Large" (Apache) or "413 Request Entity Too Large" (nginx)
Media → Add New (drag and drop)A red banner: "Unexpected response from the server. The file may have been uploaded successfully. Check in the Media Library or reload the page." The row sits at 100%
Block editor, Image blockA small dark notice: "The response is not a valid JSON response."

Here is the form case on Apache 2.4.69, with a 2.5 MB zip and LimitRequestBody at 1 MB:

A white WordPress error box. The heading says Request Entity Too Large. Under it: The requested resource does not allow request data with POST requests, or the amount of data provided in the request exceeds the capacity limit. Then Apache/2.4.69 (Debian) Server at localhost Port 8904, then The link you followed has expired. and a Please try again link.
Plugins → Add New → Upload Plugin on WordPress 7.1.4. The top part is Apache's page; the last two lines are WordPress, which ran afterwards with an empty form.

The last two lines are not a second error. On Apache with PHP as a module, Apache sent its 413 and WordPress still started, with no form data. Its security check then failed and added "The link you followed has expired." The status code stayed 413. I did not test PHP-FPM.

The drag-and-drop uploader is the one that confuses people. It shows no 413 at all:

The Upload Media screen. A red-edged banner says: Unexpected response from the server. The file may have been uploaded successfully. Check in the Media Library or reload the page. Under the upload box it says Maximum upload file size: 64 MB. A row for photo.jpg shows a full blue bar labelled 100%.
Media → Add New on WordPress 7.1.4. The page promises 64 MB, and the 2.1 MB photo still stops. The network panel shows a 413 for async-upload.php.

The text comes from the string http_error in wp-includes/script-loader.php. The uploader shows it for any answer it cannot read, so the banner never says 413. The number under the box, "Maximum upload file size: 64 MB", only reflects PHP's limits. WordPress cannot see the web server's.

The block editor shows yet another sentence:

An empty Image block with Upload, Media Library and Insert from URL buttons. A dark notice at the bottom says: The response is not a valid JSON response.
The editor's wording for the same 413. I sent the file with the editor's own upload function from the browser console, because the Upload button opens a file dialog that a script cannot drive.

The two tools that see the status are curl and your browser's network panel:

Terminal
curl -i -F "async-upload=@photo.jpg" https://example.com/wp-admin/async-upload.php
Output, Apache
HTTP/1.1 413 Request Entity Too LargeServer: Apache/2.4.69 (Debian)Connection: closeContent-Type: text/html; charset=iso-8859-1

Note that Connection: close. The server hangs up on the request. nginx's documentation warns that "browsers cannot correctly display this error", which is why you may see a stuck bar or a generic failure instead of the page.

How it works#

A request passes several gates before WordPress saves the file. The web server is first. It reads the size of the request, compares it with its limit, and answers 413 at once if it is over. WordPress never receives the file (on nginx, PHP does not even start), so nothing in debug.log and nothing in WordPress can show you why.

Four stacked boxes. 1, the web server: Apache LimitRequestBody or nginx client_max_body_size, too big gives a 413 and WordPress never receives the file. 2, PHP post_max_size: too big and WordPress says the link you followed has expired. 3, PHP upload_max_filesize: too big gives the upload_max_filesize message. 4, WordPress checks the file type and saves it.
This page is gate 1. Gates 2 and 3 are PHP's, and have their own pages.

I made each gate refuse the same 2.1 MB photo, one at a time, with the other two set to 64 MB. All requests went to wp-admin/async-upload.php with a valid login and nonce:

Gate set low (1 MB)StatusWhat came back
LimitRequestBody 1048576413Apache's "Request Entity Too Large" page
PHP post_max_size403WordPress's "The link you followed has expired."
PHP upload_max_filesize200{"success":false,"data":{"message":"The uploaded file exceeds the upload_max_filesize directive in php.ini."}}
None (all 64 MB)200{"success":true,...} and the file in the library

Only the first one is a 413. A 403 or a readable PHP message means you are past the web server. That is the quickest way to tell whether this page is the right one.

Where the limit counts#

The limit is on the size of the whole request, not of your file. A form upload adds a few hundred bytes of header and boundary text. With LimitRequestBody 1048576, I sent plain bodies of three sizes to a page that does not care:

Body size (bytes)Status
1,048,000200
1,048,576200
1,049,000413

So a file just under the limit can still be refused. A static file on the same site, readme.html, also answered 413 to a big POST. The limit applies to the folder, not to WordPress.

Two servers in a row#

Many hosts put nginx in front of Apache. Each one has a limit, and the smaller one wins. I ran an nginx container in front of the lab's Apache, with one 2.1 MB photo:

nginx client_max_body_sizeApache LimitRequestBodyResultWhose page
1m1 MB413nginx
64m1 MB413Apache
64m64 MB200none
1m64 MB413nginx
064 MB200none

The second row is the trap. After raising nginx, the 413 stayed, and the Server header still said nginx/1.31.8, because nginx passes Apache's answer through and puts its own name on it. Only the page text, Apache/2.4.69 (Debian) Server at …, showed who refused. When nginx itself refuses, its error log says:

nginx error log
[error] client intended to send too large body: 2081447 bytes, client: 192.168.65.1, server: , request: "POST /wp-login.php HTTP/1.1", host: "localhost:18413"

Apache's default is not the cause#

Older guides say Apache has no limit by default. That is true up to Apache 2.4.53. From 2.4.54 the default is 1 GiB. I tested the lab's Apache 2.4.69 with no LimitRequestBody line at all: a 1 GiB request returned 200 and a 1100 MB request returned 413. For a photo or a plugin, you will never reach that. If Apache refuses a small file, someone set a limit, so look for the line.

What does not fix it#

  • ini_set() or upload_max_size in functions.php. A 413 happens before PHP can read the file, so no PHP code can change it. Also, upload_max_size is not a PHP setting; the real names are upload_max_filesize and post_max_size. The sibling page file exceeds the maximum upload size shows that ini_set() returns false for both anyway.
  • php_value lines in .htaccess for a 413 from nginx. nginx does not read .htaccess at all.
  • Raising only the PHP limits. On the lab, post_max_size and upload_max_filesize at 64M and LimitRequestBody at 1 MB still gave 413.
  • Clearing the browser cache. The response comes from the server and I confirmed the status in the network panel each time.

Other pages that may be the real problem#

If the status is 403 and the page says "The link you followed has expired.", see that page. A 403 with the web server's own page is something else; see 403 Forbidden. A 504 after a long wait is a timeout, not a size limit; see 504 Gateway Timeout. A 500 after you edit .htaccess means a line your server does not understand; see 500 Internal Server Error. To read PHP's two limits at any time, use Tools → Site Health → Info → Media Handling; the Site Health guide explains that screen.

Sources

  1. Apache core: LimitRequestBody · Default 1073741824 (2.4.54 and later), 0 means unlimited, allowed in .htaccess
  2. nginx ngx_http_core_module: client_max_body_size · Default 1m, 413 when exceeded, 0 disables the check, and that browsers cannot correctly display the error
  3. 413 Content Too Large, MDN · The status: the request was larger than limits defined by the server. Former name Payload Too Large
  4. PHP manual: core php.ini directives · post_max_size and upload_max_filesize
  5. WordPress core, script-loader.php (uploader strings) · The http_error string the multi-file uploader shows for any bad response
Newsletter

One email when something breaks or changes.

New plugins and re-tested guides, about twice a month. Never a sales pitch.