You're importing a database dump in phpMyAdmin, or a customer is trying to upload a 40MB product video, and the browser just throws back "413 Request Entity Too Large" - no explanation, no line number, nothing in your WordPress error log. That's because this one usually isn't coming from WordPress or PHP at all. It's the web server or the CDN in front of it slamming the door before your request ever reaches PHP. Here's how to find which layer is doing it and fix it properly.
What a 413 actually means
A 413 is the server telling you: "the body of this request is bigger than I'm configured to accept, so I'm not even going to try processing it." That's different from a PHP upload error like upload_max_filesize, which at least lets the request through and then rejects the file inside PHP. A 413 gets thrown before PHP ever runs - which is why increasing PHP limits alone often doesn't fix it.
You'll typically see it when:
- Uploading a large image, video, or zip through wp-admin or a plugin uploader
- Importing a large
.sqlfile through phpMyAdmin - Submitting a big form (file attachments, bulk data) through an API endpoint
- Restoring a large backup archive through a custom import tool
Find out which layer is blocking it first
Before changing any config, look at the actual error page - it tells you who's talking:
| What you see | Likely source |
|---|---|
| Plain "413 Request Entity Too Large" with an nginx signature at the bottom | Nginx client_max_body_size |
| Apache-style error page, or nothing but a blank failure | Apache LimitRequestBody or mod_security |
| Cloudflare-branded error page (orange cloud logo) | Cloudflare's edge upload cap |
| WordPress admin notice mentioning "upload_max_filesize" | PHP, not really a 413 - different fix |
Open the request in your browser's dev tools (Network tab) and check the response headers - a Server: cloudflare or Server: nginx header confirms which layer answered before your origin app got involved.
Fix 1: Nginx's client_max_body_size (VPS / dedicated servers)
If you manage your own Nginx config on a Getwebup VPS, the default limit is just 1MB - small enough that almost any real upload trips it. Raise it in the right context:
server {
listen 443 ssl;
server_name example.com;
client_max_body_size 128M;
location / {
proxy_pass http://127.0.0.1:8080;
}
}You can set client_max_body_size in the http, server, or location block - the most specific one that matches your request wins. If Nginx is acting as a reverse proxy in front of Node, PHP-FPM, or another app, the limit has to be raised in the server or location block that actually proxies the upload request, not just at the top of the file. Then test and reload:
sudo nginx -t
sudo systemctl reload nginxSkip the reload and the change won't take effect - Nginx doesn't re-read config on save.
Fix 2: Apache's LimitRequestBody (cPanel and Apache/LiteSpeed VPS)
Most Getwebup cPanel hosting runs Apache or LiteSpeed rather than raw Nginx, so you won't have a nginx.conf to edit. Check your site's .htaccess for a stray limit first:
# Remove or raise this if present - 0 means unlimited
LimitRequestBody 10485760If there's no explicit LimitRequestBody directive in .htaccess or the vhost config, the 413 is almost always coming from a security module (mod_security) or, more often on shared hosting, from PHP's own post_max_size rejecting the request body - which technically returns a different error but gets reported by users as "the same thing." On cPanel, fix that side through MultiPHP INI Editor:
upload_max_filesize = 128M
post_max_size = 128MIf your account still throws a 413 after that, it's a hosting-level Apache/LiteSpeed cap outside your account's control - open a support ticket rather than guessing at .htaccess rules, since some of these limits live in the server-wide config.
Fix 3: Cloudflare's 100MB hard limit
If your domain is proxied through Cloudflare (orange cloud in DNS), there's a limit you can't raise from your origin server at all: Cloudflare caps request bodies at 100MB on every plan, including Enterprise unless you specifically buy the higher-tier upload add-on. No origin config change gets around this - the request never reaches your server.
Ways around it:
- DNS-only (grey cloud) for the specific upload endpoint - if you only need this for an admin-only import tool, temporarily disabling the Cloudflare proxy for that subdomain removes the cap (at the cost of losing Cloudflare's protection on that hostname).
- Chunked or resumable uploads - use a plugin or upload library (tus, resumable.js) that splits large files into small chunks well under 100MB each, then reassembles them server-side.
- Direct-to-storage uploads - for very large media, upload straight to an S3-compatible bucket with a presigned URL instead of routing the file through your web server at all.
Importing a large database dump through phpMyAdmin
A 413 on a phpMyAdmin import is really just this same stack applied to a form upload. Rather than pushing PHP and web-server limits higher and higher for an occasional big import, it's usually faster to skip the browser entirely:
mysql -u dbuser -p dbname < backup.sqlOr, if you only have cPanel access without SSH, compress the dump and use cPanel's Backup Wizard / "Restore a MySQL Database Backup" tool, which isn't bound by the same upload path as phpMyAdmin's import form.
The 413's near neighbours
A 413 is a size limit applied to the request body. Two other errors are the same idea applied elsewhere in the request, and they get mistaken for each other constantly because all three are rejections that happen before your application runs.
- 400 Bad Request: Request Header Or Cookie Too Large - the same class of limit applied to the headers instead. If the request that fails has no upload in it at all, this is almost certainly the one you want; an overgrown
Cookieheader is the usual cause. - ERR_CONNECTION_RESET - what an oversized upload looks like when a security layer kills the connection rather than answering with a status code. If the browser shows no error page at all, the request never got a 413 to display.
The quickest way to tell them apart is whether you get a status code. A 413 or a 400 means a server answered and explained itself; a connection error means nothing did.
Prevention checklist
| Layer | Directive | Typical default |
|---|---|---|
| Nginx | client_max_body_size | 1M |
| Apache | LimitRequestBody | 0 (unlimited) unless set |
| PHP | upload_max_filesize / post_max_size | 2M - 64M depending on host |
| Cloudflare | Max upload size | 100MB, not adjustable on most plans |
Whenever you raise one of these, raise the others to match - the smallest limit in the chain is always the one that wins. And if uploads are a regular part of your site (a course platform, a media-heavy WooCommerce store), it's worth setting realistic limits once across every layer instead of chasing a fresh 413 every time a customer tries something bigger than last time.