Fix 413 Request Entity Too Large on Nginx and Apache

Updated 5 November 2026 · By Brent Alexis

Short answer: a 413 Request Entity Too Large means an upload was bigger than a size limit somewhere between the visitor and your app. On Nginx it's almost always client_max_body_size, which defaults to just 1 MB: set it in the server block, for example client_max_body_size 64m;, then test and reload. For WordPress and other PHP sites, raise PHP's upload_max_filesize and post_max_size too, because PHP rejects big uploads without a 413.

Every Nginx, PHP and Apache case on this page was reproduced in the lab: the official nginx Docker image (Nginx 1.30.6) in front of a test app, Debian 12's packages (Nginx 1.22.1, PHP 8.2.35) with ProxyForge's WordPress output, and the official Apache image (2.4.68) with a reverse proxy and a local CGI script: 45 checks. The Cloudflare limits come from Cloudflare's documentation. How it's tested

Which limit refused it?

Every layer has its own limit, and the first one that's too small wins. The response usually tells you which layer it was:

LayerDefault limitWhat you see
Cloudflare (proxied site)100 MB on Free and ProA 413 page from Cloudflare, before your server sees anything
Nginx1 MBA plain 413 page with nginx at the bottom, and a line in the Nginx error log
Apache1 GB (2.4.54 and newer)An Apache 413 page, but only for requests Apache handles itself (in our lab, not for a reverse proxy)
PHP2 MB per file, 8 MB per requestNo 413: the upload arrives with an error or empty, and the page loads normally
Your appVaries by frameworkWhatever error the app returns or logs

Nginx: client_max_body_size

Nginx refuses any request body over 1 MB unless you raise client_max_body_size. The error log says:

[error] 52#52: *3 client intended to send too large body: 1100000 bytes

Fix: set it in the server block of the site, then test and reload:

server {
    # ...
    client_max_body_size 64m;
}
sudo nginx -t && sudo systemctl reload nginx

PHP and WordPress: no 413, just an empty upload

Once Nginx lets the upload through, PHP applies its own two limits. Their defaults are small, and neither gives a 413:

SettingDefaultOver the limit
upload_max_filesize2MThe upload reaches PHP, but PHP drops the file and sets error 1 (UPLOAD_ERR_INI_SIZE). The page still returns 200.
post_max_size8MPHP drops the whole request body: no file and no form fields at all. Still a 200.

For the second one, the Nginx error log gets a line from PHP:

[error] 6870#6870: *9 FastCGI sent in stderr: "PHP message: PHP Warning:  POST Content-Length of 9000209 bytes exceeds the limit of 8388608 bytes in Unknown on line 0" while reading response header from upstream

Fix: raise both, keeping post_max_size at least as big as upload_max_filesize, and keep Nginx's client_max_body_size at or above them. For a PHP-FPM pool, add these lines to its pool file (/etc/php/8.X/fpm/pool.d/www.conf on Debian and Ubuntu, /etc/php-fpm.d/www.conf on RHEL), or set the same values in php.ini:

php_admin_value[upload_max_filesize] = 64M
php_admin_value[post_max_size] = 64M

Then restart PHP-FPM (for example sudo systemctl restart php8.2-fpm, or php-fpm on RHEL). Check the values PHP-FPM is really using with php-fpm8.2 -i | grep -E "upload_max_filesize|post_max_size": the php command on the terminal can read a different php.ini than PHP-FPM. Checked on Debian 12 (PHP 8.2.35) with Nginx at 10 MB: with PHP's defaults a 1.5 MB upload worked, a 3 MB file came through as error 1 and a 9 MB upload arrived empty. After adding the two pool lines and restarting PHP-FPM, the 9 MB upload went through.

WordPress shows PHP's message for the first case: "The uploaded file exceeds the upload_max_filesize directive in php.ini."

Apache: LimitRequestBody

Since Apache 2.4.54, LimitRequestBody defaults to 1 GB (before that it was unlimited). Set it lower in the server config, a virtual host or a <Location>, in bytes:

LimitRequestBody 10485760

In our lab on Apache 2.4.68, LimitRequestBody 10485760 stopped an 11 MB upload to a script Apache runs itself (a CGI script) with a 413, wherever it was set: server config, virtual host or <Location>. At Apache's default log level nothing about the limit reaches the error log; the CGI script only logged AH01270: Error reading request entity data. To see the reason, set LogLevel info for a while. Then the error log says:

AH01588: Requested content-length of 11000000 is larger than the configured limit of 10485760

Put LogLevel back to warn afterwards, because info logs a lot.

It didn't limit a reverse proxy. In the same lab, an 11 MB upload to an app behind ProxyPass went through in all three places, with or without a Content-Length header, and a request announcing 2 GB got no 413 either: Apache just waited for the body. Apache's source code used to say so, in a comment reading "LimitRequestBody does not affect Proxy requests". That comment and the matching documentation note were removed in 2.4.54, when the 1 GB default arrived, but proxied uploads still weren't limited in our test. So for a reverse proxy, set the limit in the app itself, or put Nginx in front with client_max_body_size.

On shared hosting where you only have .htaccess, the limit you'll hit is usually PHP's, not Apache's. The host's control panel often has a PHP settings page for upload_max_filesize and post_max_size.

Cloudflare: 100 MB on Free and Pro

If your site is proxied through Cloudflare (orange cloud), Cloudflare refuses uploads over 100 MB on the Free and Pro plans and 200 MB on Business. Enterprise starts at 500 MB and can be raised to 5 GB from the zone's Network page (source: Cloudflare's 413 page, checked 5 November 2026). Your server never sees those requests, so no Nginx or Apache setting helps. Options are to upload in smaller chunks, send uploads to a hostname that isn't proxied (DNS only), or move to a bigger plan. This part isn't lab-tested.

Check the fix

Upload a file a little bigger than the old limit through your real upload form, then look at the response and the logs:

sudo tail -n 5 /var/log/nginx/error.log

No new client intended to send too large body line means Nginx let it through. If the upload still fails without a 413, the limit is in PHP or the app. If a config change seems to do nothing, check the reload applied: see nginx -s reload said OK, but my change didn't apply.

Generate a config with the upload size you need →

How to use ProxyForge · FAQ: common errors · Guides · What's new · About