← Debugging Guides

阅读中文版本

Express PayloadTooLargeError — Request Body Over Limit

Resolve Express body-parser 413 Entity Too Large errors by matching the JSON and urlencoded limits to real payload sizes instead of blindly raising them.

beginnerdebuggingnodejsexpresshttp

Symptoms

  • The API returns 413 with "request entity too large" only for big submissions
  • Small JSON succeeds while a slightly larger object returns 413
  • The error surfaces from body-parser, not from your route handler

Possible causes

  • The default JSON limit of 100kb is smaller than the request being sent
  • A reverse proxy also caps body size and returns 413 before Express sees it
  • A multipart or large text payload is routed through the JSON parser

Diagnosis steps

Confirm which component rejects the body

curl -i -X POST https://api.example.com/items -H 'Content-Type: application/json' --data-binary @large.json

Interpretation

If the 413 comes with the proxy Server header it is the proxy; if body-parser logs it, it is the app limit.

Measure the actual payload size

wc -c large.json

Interpretation

Compare against the configured limit. Set the limit a little above the real maximum rather than to unlimited.

Inspect parser configuration

grep -rn "bodyParser\|express.json" src/ | grep -i limit

Interpretation

The configured limit (or its absence, meaning the 100kb default) explains the threshold.

Root cause

body-parser rejects a request as soon as the streamed body exceeds its configured limit, raising PayloadTooLargeError before your handler runs. Any proxy in front may impose a second, often smaller, cap.

Fix

Set an explicit, bounded limit on each parser (for example express.json({ limit: "1mb" })), route large uploads through a streaming/multipart handler instead of the JSON parser, and align the proxy client_max_body_size to the same value.

Risk note

An unlimited body limit is a denial-of-service vector; always bound it and validate Content-Length.

Verify the fix

Post a payload just under the new limit and confirm 200, then post one just over it and confirm a controlled 413 with a helpful message rather than a crash.

Symptoms

This guide profiles the failure behind “Express PayloadTooLargeError — Request Body Over Limit”. It walks through the observable symptoms, a reproducible diagnosis path, the underlying root cause, the concrete fix, and how to verify the change and prevent a regression.

Observed symptoms include:

  • The API returns 413 with “request entity too large” only for big submissions
  • Small JSON succeeds while a slightly larger object returns 413
  • The error surfaces from body-parser, not from your route handler

Reproduce and Diagnose

Reproduce the failure in isolation before changing any code. Work through the checks below in order; each one narrows the search space.

Step 1: Confirm which component rejects the body

curl -i -X POST https://api.example.com/items -H 'Content-Type: application/json' --data-binary @large.json

If the 413 comes with the proxy Server header it is the proxy; if body-parser logs it, it is the app limit.

Step 2: Measure the actual payload size

wc -c large.json

Compare against the configured limit. Set the limit a little above the real maximum rather than to unlimited.

Step 3: Inspect parser configuration

grep -rn "bodyParser\|express.json" src/ | grep -i limit

The configured limit (or its absence, meaning the 100kb default) explains the threshold.

Likely contributors, in order of frequency:

  • The default JSON limit of 100kb is smaller than the request being sent
  • A reverse proxy also caps body size and returns 413 before Express sees it
  • A multipart or large text payload is routed through the JSON parser

Root Cause

body-parser rejects a request as soon as the streamed body exceeds its configured limit, raising PayloadTooLargeError before your handler runs. Any proxy in front may impose a second, often smaller, cap.

The Fix

Set an explicit, bounded limit on each parser (for example express.json({ limit: “1mb” })), route large uploads through a streaming/multipart handler instead of the JSON parser, and align the proxy client_max_body_size to the same value.

Watch out: An unlimited body limit is a denial-of-service vector; always bound it and validate Content-Length.

import express from 'express';
const app = express();

app.use(express.json({ limit: '1mb' }));
app.use(express.urlencoded({ extended: true, limit: '1mb' }));

// 413 arrives before this handler when the limit is exceeded.
app.post('/items', (req, res) => res.json({ received: req.body }));

app.use((err, _req, res, _next) => {
  if (err.type === 'entity.too.large') return res.status(413).json({ error: 'payload too large' });
  res.status(500).json({ error: 'internal error' });
});

Verify and Prevent

Post a payload just under the new limit and confirm 200, then post one just over it and confirm a controlled 413 with a helpful message rather than a crash.

Once verified, add a regression test that reproduces the original symptom so the failure cannot silently return.

This class of failure is usually environmental rather than pure logic, so capture the exact command, the environment variables, and the working directory in your bug report. Reproduce it in the smallest possible script, then widen the scope only once the minimal case is understood. A short written checklist for this failure mode saves hours the next time it appears.