# 413 Request Entity Too Large in nginx: How to Raise the Upload Limit

```text
413 Request Entity Too Large
nginx
```

The server refused the request because its body — usually a file upload — is bigger than it allows. HTTP now calls this status [413 Content Too Large](/http/413); nginx still prints the old name. nginx's default limit is just **1 MB**, so the first large upload on a new server almost always hits it.

## Raise the limit in nginx

`client_max_body_size` can go in the `http`, `server` or `location` block:

```nginx
server {
    # ...
    client_max_body_size 50m;

    location /api/upload {
        client_max_body_size 500m;  # larger limit for one endpoint
    }
}
```

Then test the config and reload:

```bash
sudo nginx -t && sudo systemctl reload nginx
```

`client_max_body_size 0;` disables the check entirely — better to set a real ceiling. nginx checks the request's [Content-Length](/headers/content-length) up front, so an oversized upload is rejected before it's transferred.

## Then check every other layer

Each layer in front of your code has its own limit, and the smallest one wins. If the 413 persists after changing nginx, look at the response body and headers to see which layer sent it.

**PHP** — two settings in `php.ini`, then restart PHP-FPM:

```ini
upload_max_filesize = 50M
post_max_size = 50M
```

The defaults are 2M and 8M. `post_max_size` must be at least as large as `upload_max_filesize`.

**Express** — body parsers default to 100 KB and answer with `PayloadTooLargeError: request entity too large`:

```js
app.use(express.json({ limit: "10mb" }));
app.use(express.urlencoded({ extended: true, limit: "10mb" }));
```

For file uploads, use a streaming parser such as multer or busboy and set its `limits` instead.

**Next.js** — Server Actions accept 1 MB by default; raise it in `next.config.js`:

```js
module.exports = {
  experimental: {
    serverActions: { bodySizeLimit: "10mb" },
  },
};
```

In the Pages Router, API routes have their own 1 MB default, set per route with `export const config = { api: { bodyParser: { sizeLimit: "10mb" } } }`. And if requests pass through middleware (`proxy.ts` in Next.js 16), their bodies are capped at 10 MB unless you raise `experimental.proxyClientMaxBodySize`.

**Kubernetes ingress-nginx** — set it per Ingress with an annotation:

```yaml
metadata:
  annotations:
    nginx.ingress.kubernetes.io/proxy-body-size: "50m"
```

**Hosting platforms and CDNs** have fixed ceilings you can't raise in config: Vercel Functions accept request bodies up to 4.5 MB, AWS API Gateway up to 10 MB, and Cloudflare's limit depends on your plan (100 MB on Free and Pro).

## For really large files, skip your server

Uploading big files through your app server ties up a worker for the whole transfer and runs into every limit above. Instead, have your server issue a **presigned upload URL** for S3, R2, GCS or similar, and let the browser upload straight to storage. Your server only handles a small JSON request, and the size limit becomes the storage provider's (gigabytes).

## Show a useful error

Check file sizes in the browser before uploading, so users don't wait for a 413:

```js
const MAX = 50 * 1024 * 1024;
if (file.size > MAX) {
  alert(`That file is ${(file.size / 1024 / 1024).toFixed(1)} MB; the limit is 50 MB.`);
}
```

Hit a 502 instead after raising limits? Large uploads can also time out between nginx and your app — see [how to fix 502 Bad Gateway in nginx](/blog/fix-502-bad-gateway-nginx).
