vercel/next.js · error · ApiError

Body exceeded ${bodySizeLimit} limit. To configure the body

Error message

Body exceeded ${bodySizeLimit} limit.
To configure the body size limit for Server Actions, see: https://nextjs.org/docs/app/api-reference/next-config-js/serverActions#bodysizelimit

What it means

A 413 ApiError thrown while streaming a multipart Server Action body on the edge runtime. The handler manually reads req.body chunks and accumulates byte length; once edgeBodySize exceeds bodySizeLimitBytes, this error aborts the read. bodySizeLimit comes from next.config.js serverActions.bodySizeLimit (default 1 MB).

Source

Thrown at packages/next/src/server/app-render/action-handler.ts:821

          temporaryReferences = createTemporaryReferenceSet()

          if (isMultipartAction) {
            // TODO-APP: Add streaming support
            // Read the body stream with size tracking to enforce bodySizeLimitBytes.
            // We cannot call req.request.formData() directly as that would bypass
            // the body size limit entirely.
            const edgeChunks: Uint8Array[] = []
            let edgeBodySize = 0
            const edgeReader = req.body.getReader()
            while (true) {
              const { done, value } = await edgeReader.read()
              if (done) break
              edgeBodySize += value.byteLength
              if (edgeBodySize > bodySizeLimitBytes) {
                const { ApiError } =
                  require('../api-utils') as typeof import('../api-utils')
                throw new ApiError(
                  413,
                  `Body exceeded ${bodySizeLimit} limit.\n` +
                    `To configure the body size limit for Server Actions, see: https://nextjs.org/docs/app/api-reference/next-config-js/serverActions#bodysizelimit`
                )
              }
              edgeChunks.push(value)
            }
            // Reconstruct a Blob from the buffered chunks and parse formData from it.
            // Note: we must pass the original Content-Type as an explicit header
            // rather than relying on the Blob's `type`. The Blob constructor
            // normalizes `type` to ASCII lowercase per the File API spec, which
            // would lowercase the multipart boundary parameter (e.g.
            // `boundary=----WebKitFormBoundaryAbCdEf`). The body bytes contain the
            // original mixed-case boundary delimiter, so a lowercased boundary
            // would fail to match and `formData()` would throw. An explicit header
            // on the Request takes precedence over the Blob's normalized type.
            const edgeBodyBlob = new Blob(edgeChunks as BlobPart[])
            const formData = await new Request('http://n/', {

View on GitHub (pinned to 0ae8c72462)

Solutions

  1. Raise the limit in next.config.js: experimental.serverActions.bodySizeLimit (e.g. '5mb') to accommodate the upload size.
  2. If the upload is genuinely large, prefer direct-to-storage uploads (e.g. presigned S3 URLs) rather than routing the file through a Server Action.
  3. Validate file size on the client before submitting to give the user early feedback.
  4. Confirm the limit string format is correct (e.g. '2mb', '500kb') so it parses to the intended bytes.

Example fix

// next.config.js -- before
// module.exports = { /* no serverActions config */ }

// after
// module.exports = {
//   experimental: { serverActions: { bodySizeLimit: '5mb' } } 
// }
Defensive patterns

Strategy: validation

Validate before calling

// Client-side size guard before submitting a multipart Server Action.
const MAX = 1 * 1024 * 1024 // match serverActions.bodySizeLimit
function totalSize(formData: FormData): number {
  let n = 0
  formData.forEach((v) => { n += typeof v === 'string' ? v.length : (v as File).size })
  return n
}
if (totalSize(fd) > MAX) { alert('Too large'); return }

Prevention

When it happens

Trigger: An edge-runtime Server Action receives a multipart/form-data POST (e.g. a form with a file upload or large fields). During the chunked read loop (lines 814-828), the cumulative edgeBodySize surpasses the configured limit and the ApiError is thrown.

Common situations: File uploads via Server Actions exceeding the default 1 MB; forms with many or large fields; users pasting large text. The limit is a safety/DoS guard, so legitimate large uploads need a config bump.

Related errors


AI-assisted analysis of vercel/next.js@0ae8c72462 (2026-08-06). Data as JSON: /api/errors/90a63739e4394a28. Report an issue: GitHub.