413 Payload Too Large

The request body, usually a file upload, was bigger than the server or host accepts, so it was rejected before your code could handle it.

Browser console
POST http://localhost:3000/api/upload 413 (Payload Too Large)

Also appears as

  • POST https://my-app.com/api/upload 413 (Content Too Large)
  • PayloadTooLargeError: request entity too large
  • Body exceeded 1 MB limit. To configure the body size limit for Server Actions, see: https://nextjs.org/docs/app/api-reference/next-config-js/serverActions#bodysizelimit
  • The object exceeded the maximum allowed size
  • 413 Request Entity Too Large

Prompt to fix it

Uploads in my app fail with "413 Payload Too Large". Find the request that fails and which layer rejects it: our framework’s body parser, the hosting platform’s request limit, a proxy, or the storage bucket’s file size limit. For files, change the flow so the browser uploads straight to storage with a signed upload URL and our API only receives the file path. For JSON bodies, raise the limit where it’s configured, within the host’s maximum. Add a file size check before upload with a clear message, and don’t send files as base64 inside JSON.

Paste into Layerwise or any AI coding tool.

What it means

Every server caps how much data one request can carry. A 413 means the body went over that cap, so the server, the host, or a framework layer refused it, often before your route code ran. Uploads are the usual trigger, along with images sent as base64 text inside JSON.

The cap often sits in a layer you didn’t write. Express’s express.json() accepts 100 KB by default. Next.js Server Actions accept 1 MB unless you raise bodySizeLimit. Vercel Functions accept request bodies up to 4.5 MB, and Supabase Storage allows files up to 50 MB on the Free plan. Over HTTP/2, Chrome labels it “Content Too Large,” the status’s newer official name.

Raising a limit only goes so far, because host limits like Vercel’s apply on top of anything you configure. For files, the lasting fix is to upload from the browser straight to storage (Supabase Storage, Amazon S3, Vercel Blob, or Cloudflare R2) with a signed upload URL, then send only the file’s path to your API.

Common causes

  • The app sends files through its own API route, and the file is larger than the host’s request limit.
  • Images are converted to base64 and embedded in JSON, which makes them about a third larger and trips a JSON body limit.
  • A framework default is low, such as 100 KB for express.json() or 1 MB for Server Actions.
  • The storage bucket or project has a maximum file size below the size of the upload.
  • A proxy in front of the server rejects it, such as nginx with its default client_max_body_size of 1 MB.

How to fix it

  1. Check the request’s size in the Network tab, and read the response to see which layer answered: your framework, the host, or storage.
  2. For JSON bodies you control, raise the limit where it’s set, such as express.json({ limit: '5mb' }) or experimental.serverActions.bodySizeLimit in next.config.ts.
  3. For files, upload directly from the browser to storage with a signed upload URL, and send only the file path to your API.
  4. Send files as FormData rather than base64 inside JSON.
  5. Check the file size in the browser before uploading and show the limit in a clear message.
  6. If storage rejected it, raise the bucket’s or project’s file size limit in the storage settings, within what your plan allows.

Example fix

// next.config.ts: Server Actions accept 1 MB by default.
import type { NextConfig } from 'next';

const nextConfig: NextConfig = {
  experimental: {
    // Stay under your host's own limit (4.5 MB on Vercel).
    serverActions: { bodySizeLimit: '4mb' }
  }
};

export default nextConfig;
All errors
POST https://my-app.com/api/checkout 500 (Internal Server Error)

500 Internal Server Error

The server’s code threw an error or crashed while handling the request, and the real error message is waiting in the server logs.

504: GATEWAY_TIMEOUT Code: FUNCTION_INVOCATION_TIMEOUT ID: iad1::q8n2v-1793091406762-4b1e2f9a7c3d

FUNCTION_INVOCATION_TIMEOUT

A Vercel Function ran past its time limit, so Vercel stopped it and returned a 504 in place of your response.

BadRequestError: 400 Your input exceeds the context window of this model. Please adjust your input and try again.

Context length exceeded

The text sent to the model, including chat history, documents, and tool results, is more than the model can read in one request.

Access to fetch at 'https://api.example.com/items' from origin 'http://localhost:5173' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

Blocked by CORS policy

The browser hid a response from another site because that server never said your site is allowed to read it.

Build with an agent that checks its work

The Layerwise agent clicks through the live preview and reads the console, so it catches errors before you do.