Express.js File Upload Limits: Configuration, Multer, and Body Parser
Express file upload limits depend on whether requests pass through built-in body parsers or streaming multipart middleware. Express body-parser defaults to 100KB for JSON and URL-encoded payloads, while Multer accepts unlimited payloads unless constrained by limits.fileSize. Raising express.json limits does not process multipart form-data. Resolving 413 Payload Too Large errors requires tuning middleware, adjusting reverse proxy ceilings, or offloading files to persistent storage.
What Are Express File Upload Limits and What Causes 413 Errors?
Handling file ingestion in an Express application requires coordinating two separate parsing layers: built-in body parsers for structured text payloads, and streaming multipart parsers for binary assets. When developers conflate the two by adding express.json({ limit: '50mb' }), incoming multipart form-data requests still fail or trigger unhandled errors before reaching route handlers.
The Express.js file upload limit is the maximum payload size permitted by Express middleware and underlying Node.js HTTP servers before terminating the connection with a 413 Payload Too Large status code. Understanding where this threshold originates determines whether a configuration adjustment belongs in application code, middleware options, or upstream proxy settings.
In an Express backend, incoming HTTP requests arrive over TCP sockets as raw byte streams. Express does not parse incoming request bodies out of the box. Instead, it delegates payload processing to middleware functions that inspect the incoming Content-Type header, read stream chunks from the network socket, and assemble the parsed result onto the req.body or req.files object.
Anatomy of the HTTP 413 Error
When an incoming request exceeds a configured size threshold, the responsible parser terminates stream consumption immediately, closes the socket connection, and constructs an error object. In Express, this failure manifests as an HTTP 413 status code:
- PayloadTooLargeError in body-parser: Generated when
express.json(),express.raw(), orexpress.urlencoded()consumes more bytes than its configuredlimitoption. The error object containsstatus: 413,type: 'entity.too.large', and the byte limit that was violated. - LIMIT_FILE_SIZE in Multer: Emitted when an uploaded file in a
multipart/form-datarequest exceeds the byte threshold defined inlimits.fileSize. Multer constructs aMulterErrorobject withcode: 'LIMIT_FILE_SIZE'. - Request Entity Too Large in Reverse Proxies: Returned by upstream reverse proxies like Nginx or cloud edge networks before the request ever reaches the Node.js event loop.
Comparing Upload Ceilings Across Node.js and Infrastructure
Payload constraints exist at every layer of the network path. The following comparison outlines default thresholds, configuration options, and failure mechanisms across Node.js runtimes, middleware, reverse proxies, and AI agent runtimes:
In automated agent environments, similar constraints govern document intake. According to the Anthropic Help Center, Claude chat sessions accept up to 20 files at up to 500MB each, while Claude Projects accept files up to 30MB each with no fixed file-count cap, bounded only by the model's context window. Crossing local server limits or agent context boundaries produces identical operational friction: stalled pipelines and truncated document collections.
Related guides
- PHP File Upload Limit: upload_max_filesize, post_max_size, and Memory LimitsThe PHP file upload limit is governed by configuration directives in php.ini, primarily upload_max_filesize and...
- Base64 File Size Limit: Payload Overhead, Memory Usage, and API ConstraintsWhile Base64 encoding imposes no theoretical file size limit, transmitting binary files as ASCII text causes an...
- How to Implement Generative UI File Uploads with Fastio APIGenerative UI file uploads use LLMs to dynamically render interactive upload components backed by the Fastio API based...
- How to Test Fastio API File Uploads with VitestGuide to testing fastio api file uploads with vitest: Testing Fastio file uploads with Vitest involves using vi.mock()...
- ChatGPT File Upload Limits: How to Handle Large Files and FoldersChatGPT limits documents to 512MB per file, uploads to 80 files every 3 hours, and upload storage to 25 GB per user,...
- CSV File Size Limits: AI Assistant Upload Caps, Parsing Ceilings, and FixesCSV file size limits vary from strict row boundaries in spreadsheets to memory and token constraints in AI chat...
More on this subject: Agent File and Document Workflows (332 guides)
How to Configure Body Parser Limits for JSON and URL-Encoded Payloads
A frequent misunderstanding in Node.js development is attempting to resolve file upload rejections by increasing express.json() limits. The built-in express.json() middleware parses incoming request bodies formatted as application/json. It does not parse multipart/form-data requests containing binary file streams.
According to the official Express body-parser documentation, the middleware controls the maximum request body size with a default limit of '100kb'. When an application receives JSON payloads containing Base64-encoded file contents, image thumbnails, or extensive document strings that exceed 102,400 bytes, Express halts processing and emits a PayloadTooLargeError.
Adjusting JSON and URL-Encoded Middleware Limits
To allow larger JSON or form-urlencoded payloads, pass a numeric byte value or string representation to the middleware options during initialization:
const express = require('express');
const app = express();
// Configure JSON parser limit for structured data payloads
app.use(express.json({ limit: '10mb' }));
// Configure URL-encoded form parser limit
app.use(express.urlencoded({ limit: '10mb', extended: true }));
Accepted string formats include units such as '500kb', '10mb', or '1gb'. The parser hands these strings directly to the bytes utility library for conversion into integer byte values.
Returning Structured JSON Errors for 413 Exceptions
By default, Express handles uncaught middleware errors by outputting an HTML error document with a stack trace. For REST APIs and automated services, clients expect structured JSON responses. Add a centralized error-handling middleware function after your routes to catch body-parser errors cleanly:
// Central error handling middleware for Express body-parser
app.use((err, req, res, next) => {
if (err.type === 'entity.too.large') {
return res.status(413).json({
status: 'error',
code: 'PAYLOAD_TOO_LARGE',
message: `Request body exceeded the allowed limit of ${err.limit} bytes`,
receivedBytes: err.length,
});
}
next(err);
});
The Hidden Costs of Base64 File Uploads in JSON
Transmitting files as Base64 strings inside JSON bodies avoids configuring multipart middleware, but introduces three severe performance penalties:
- Payload Inflation: Base64 encoding expands raw binary data into four ASCII characters for every three input bytes, consuming extra network bandwidth and processing time.
- V8 String Length Boundaries: In 64-bit Node.js runtimes, string primitives cannot exceed
buffer.constants.MAX_STRING_LENGTH, which is fixed at536,870,888characters. Attempting to serialize or parse a string larger than this constant throws an immediateRangeError: ERR_STRING_TOO_LONG. - Event Loop Starvation: Decoding multi-megabyte Base64 strings into Node.js Buffer instances runs synchronously on the main thread, blocking the event loop and delaying concurrent request handling across the entire process.
For these reasons, production applications handle binary assets through dedicated multipart parsers rather than ballooning express.json() limits.
How to Set File Upload Limits with Multer and express-fileupload
To handle standard file uploads transmitted via multipart/form-data, Express applications use dedicated multipart parsing middleware. The two most common libraries are Multer and express-fileupload. Each implements file size constraints differently.
Configuring File Size Limits in Multer
Multer is an Express middleware built on top of the busboy streaming parser. By default, Multer sets no upper limit on uploaded file size (fileSize: Infinity). Leaving this setting unconfigured creates a vulnerability where an oversized upload can exhaust server memory or fill local disks.
You define file size boundaries in Multer using the limits object, specifying values as integer byte counts:
const express = require('express');
const multer = require('multer');
const path = require('path');
const app = express();
// Configure disk storage engine
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, path.join(__dirname, 'uploads'));
},
filename: (req, file, cb) => {
const uniqueSuffix = `${Date.now()}-${Math.round(Math.random() * 1e9)}`;
cb(null, `${uniqueSuffix}-${file.originalname}`);
}
});
// Enforce upload boundaries: 25 MB max per file, 5 files max per request
const upload = multer({
storage: storage,
limits: {
fileSize: 25 * 1024 * 1024, // 25 MB in bytes
files: 5, // Maximum 5 files per request
fields: 10, // Maximum non-file form fields
fieldSize: 1024 * 1024 // 1 MB maximum for metadata fields
}
});
// Route handling a single file upload
app.post('/api/upload', upload.single('document'), (req, res) => {
if (!req.file) {
return res.status(400).json({ error: 'No file received' });
}
res.status(200).json({
status: 'success',
filename: req.file.filename,
size: req.file.size
});
});
// Specialized error handler for Multer upload boundaries
app.use((err, req, res, next) => {
if (err instanceof multer.MulterError) {
if (err.code === 'LIMIT_FILE_SIZE') {
return res.status(413).json({
error: 'File size limit exceeded. Maximum allowed size is 25 MB.'
});
}
if (err.code === 'LIMIT_FILE_COUNT') {
return res.status(400).json({
error: 'Too many files uploaded in a single request.'
});
}
return res.status(400).json({ error: err.message });
}
next(err);
});
When using diskStorage, Multer automatically halts writing and unlinks temporary files from the disk when an upload crosses limits.fileSize. If you use memoryStorage(), Multer buffers incoming files in RAM as Node.js Buffer objects, which can trigger fatal V8 out-of-memory crashes when multiple concurrent uploads arrive.
Configuring File Size Limits in express-fileupload
The express-fileupload library provides a lightweight alternative that wraps busboy into a single global middleware function. It supports global payload ceilings, automatic temporary file streaming, and limit rejection parameters:
const express = require('express');
const fileUpload = require('express-fileupload');
const app = express();
// Configure global upload limits with express-fileupload
app.use(fileUpload({
limits: {
fileSize: 25 * 1024 * 1024 // 25 MB limit
},
abortOnLimit: true,
responseOnLimit: 'File size limit exceeded. Maximum payload is 25 MB.',
useTempFiles: true,
tempFileDir: '/tmp/'
}));
app.post('/api/files', (req, res) => {
if (!req.files || Object.keys(req.files).length === 0) {
return res.status(400).send('No files were uploaded.');
}
const uploadedFile = req.files.asset;
uploadedFile.mv(`./storage/${uploadedFile.name}`, (err) => {
if (err) return res.status(500).send(err.message);
res.send('File uploaded successfully.');
});
});
Setting useTempFiles: true prevents express-fileupload from holding entire file buffers in Node.js process memory, writing chunks directly to disk instead.
Scale File Ingestion Without Server Memory Crashes
Connect your applications and AI agents to persistent Fastio workspaces via remote MCP. Store multi-gigabyte files with automatic indexing and hybrid search. Monthly plans start with a 14-day free trial.
Why Reverse Proxies Reject Large Payloads Before Express Receives Them
In production architectures, Node.js rarely faces the public internet directly. Reverse proxies like Nginx, edge services like Cloudflare, and cloud load balancers sit between client requests and Express. These intermediate layers enforce their own default payload limits, often rejecting large files with an HTTP 413 response before Node.js ever receives the request.
Nginx client_max_body_size
Nginx enforces a default body size limit of 1 MB across all incoming client connections. When an upload exceeds this boundary, Nginx terminates the connection and returns its own HTML error page displaying 413 Request Entity Too Large.
To raise this limit in Nginx, configure the client_max_body_size directive inside the http, server, or location block of your Nginx configuration:
server {
listen 80;
server_name api.example.com;
client_max_body_size 50M;
location /api/upload {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_request_buffering off;
proxy_read_timeout 300s;
}
}
Setting proxy_request_buffering off; allows Nginx to pass incoming data chunks directly to Express as they arrive from the client, rather than waiting to buffer the entire file on Nginx temporary disk storage first.
Cloud Edge and Cloud Provider Payload Ceilings
Managed cloud infrastructure enforces non-negotiable payload ceilings that cannot be overridden by application code:
- Cloudflare: Free and Pro plans enforce a hard ceiling of
100 MBper request. Business plans support200 MB, and Enterprise plans allow custom thresholds upon request. Any upload exceeding these thresholds is terminated at the edge with an HTTP 413 error. - AWS API Gateway: REST and HTTP APIs impose a hard request payload limit of 10 MB. Bypassing this restriction requires using pre-signed URLs to upload directly to object storage.
- AWS Application Load Balancer (ALB): Enforces a default 1 MB limit for target group request bodies when invoking AWS Lambda, though standard EC2 target groups pass larger bodies subject to connection timeouts.
Node.js HTTP Server Header Limits
In addition to body limits, the Node.js HTTP parser enforces request header boundaries. The http.maxHeaderSize property specifies the maximum permitted size of HTTP headers, defaulting to 16 KB (16,384 bytes). Requests with oversized cookie jars or massive authorization tokens fail with an HTTP 431 Request Header Fields Too Large status code.
To increase the header size threshold when starting Node.js, pass the CLI argument or specify maxHeaderSize during server creation:
const http = require('http');
const express = require('express');
const app = express();
// Override default 16 KB header limit to 32 KB on the server instance
const server = http.createServer({ maxHeaderSize: 32 * 1024 }, app);
server.listen(3000);
Identifying the Source of a 413 Error
When diagnosing an unexpected 413 status code, inspect the response headers returned to the client:
- If the response includes
Server: nginx, Nginx terminated the request viaclient_max_body_size. - If the response includes
Server: cloudflarewith a standard Cloudflare branded error page, the edge network dropped the payload. - If the response includes
X-Powered-By: Expressor a structured JSON response generated by your custom error handler, Express middleware rejected the file.
How to Stream Large Corpora to Persistent Workspaces in Agent Architectures
Increasing server upload limits solves transient payload errors, but buffering multi-megabyte or gigabyte files inside web application processes introduces long-term stability risks. Node.js operates on a single-threaded event loop. When a server processes multiple concurrent multipart streams, memory consumption rises, garbage collection cycles increase, and the risk of unexpected process termination climbs.
In modern engineering pipelines and AI agent workflows, teams avoid streaming large file corpora directly through web application servers. Instead, they decouple ingestion by routing files to dedicated persistent storage, passing lightweight URIs or metadata pointers to downstream services.
Direct-to-Storage Architecture
In a decoupled ingestion model, the Express server acts as a coordination layer rather than a binary transit pipe:
- The client requests an upload authorization ticket or signed endpoint from the Express API.
- The Express server authenticates the caller and returns a destination endpoint.
- The client uploads the binary payload directly to persistent storage.
- Upon completion, the storage service emits an event, notifying the application that the file is available for processing.
This pattern eliminates memory spikes on the Node.js host, protects backend availability during peak upload traffic, and bypasses reverse proxy payload ceilings completely.
Managing Large File Corpora in Fastio Workspaces
For teams coordinating autonomous AI agents, developer tools, and human review, Fastio workspaces provide persistent, structured environments for file storage, retrieval, and collaboration. Rather than forcing large files through web server memory or saturating LLM context windows, document collections reside in shared workspaces where people and agents work together.
Workspaces provide foundational capabilities for scalable file handling:
- Automated Indexing with Intelligence Mode: When Intelligence Mode is enabled on a workspace, incoming files are automatically indexed for hybrid search, combining full-text search, semantic search, and metadata filtering without maintaining an external vector database.
- Remote Model Context Protocol (MCP) Server: AI agents connect to Fastio workspaces through the remote MCP server over Streamable HTTP at
https://mcp.fast.io/mcp/tools(orhttps://mcp.fast.io/mcp/codefor coding agents). To configure connections, developers consult the Fastio MCP documentation. Agents search indexed workspaces dynamically, retrieving specific citations and text passages instead of loading massive documents directly into prompt contexts. - Structured Extraction with Metadata Views: Teams configure Metadata Views to turn unstructured files into structured, queryable tables (supporting Text, Integer, Decimal, Boolean, URL, JSON, and Date & Time fields) without manual extraction rules.
- Cloud Sync Integration: Cloud Sync connects Google Drive, Dropbox, Box and OneDrive folders to a workspace, one-way or two-way, on a schedule or on demand.
- Version History and Detailed Activity Log: Every file maintains complete per-file version history. A detailed activity log records changes made across the organization (uploads, edits, moves, deletions, and share creation). Concurrency control is supported through advisory per-file locks via MCP actions (
lock-acquireandlock-releaseonstorage_manage, andlock-statusonstorage). - Scoped Roles and Branded Shares: Access controls are set per organization, workspace, and share through member roles. Branded shares (Send, Receive, Exchange) allow teams to distribute or collect files from external clients, with options to disable file downloads.
Fastio operates on a transparent subscription model. Monthly plans start with a 14-day free trial that requires a credit card. Subscriptions include:
By offloading file ingestion and semantic retrieval to indexed workspaces, developers protect Node.js Express servers from memory exhaustion while giving applications and AI agents reliable access to enterprise data.
Sources
References used to verify factual claims in this guide.
-
The default body-parser limit is 100kb for parsed request bodies unless explicitly configured, rejecting larger payloads with an HTTP 413 error.
-
Claude chat sessions accept up to 20 files at up to 500MB each, while Claude Projects accept files up to 30MB each with no fixed file-count cap, bounded only by the model's context window.
Frequently Asked Questions
What is the default file upload limit in Express?
Express imposes no direct limit on multipart file uploads because it does not include a multipart parser by default. However, its built-in body-parser middleware enforces a default limit of 100 KB on JSON and URL-encoded bodies. When using Multer for multipart uploads, the default file size limit is unlimited unless explicitly set in limits.fileSize.
Why does Express reject files with a 413 Payload Too Large error?
An HTTP 413 error indicates that the incoming request body exceeded the maximum size allowed by an active parser or upstream proxy. If uploading JSON or URL-encoded data, the payload exceeded the 100 KB limit in express.json() or express.urlencoded(). If using Multer, the file exceeded limits.fileSize. If behind Nginx, the request exceeded client_max_body_size (default 1 MB).
Does increasing express.json limit allow larger file uploads?
No. The express.json({ limit }) setting only applies to application/json payloads, such as Base64 strings. It does not parse multipart/form-data requests used for binary file uploads. Handling standard file uploads requires multipart middleware like Multer or express-fileupload.
How do I increase the file upload size limit in Multer?
Define limits.fileSize in bytes inside the multer() initialization object. For example, to establish a `25 MB` limit, specify limits: { fileSize: 25 * 1024 * 1024 }. Multer checks incoming file streams and aborts processing if any file exceeds this threshold.
How do I configure upload limits using express-fileupload?
Pass a limits object to the fileUpload() middleware during setup, such as app.use(fileUpload({ limits: { fileSize: 25 * 1024 * 1024 }, abortOnLimit: true })). Setting useTempFiles: true writes chunks to disk instead of buffering entire files in memory.
Why does Nginx return 413 before Express receives the upload?
Nginx checks the Content-Length header against its client_max_body_size setting, which defaults to `1 MB`. If the header exceeds this value, Nginx rejects the connection immediately, preventing the request from ever reaching the Node.js Express server.
What is the difference between Multer memoryStorage and diskStorage?
Multer memoryStorage buffers uploaded files entirely in RAM as Buffer instances, which can trigger fatal V8 out-of-memory crashes under concurrent large uploads. Multer diskStorage streams incoming chunks directly to disk, keeping process memory consumption low and predictable.
How can AI agents process large document collections without hitting Express upload limits?
Rather than streaming large files through Express web servers and converting them into prompt text, agents store document collections in persistent Fastio workspaces. Once Intelligence Mode is enabled, files are indexed for hybrid search, allowing agents to retrieve relevant excerpts over remote MCP without exceeding context windows or server memory limits.
Related Resources
Scale File Ingestion Without Server Memory Crashes
Connect your applications and AI agents to persistent Fastio workspaces via remote MCP. Store multi-gigabyte files with automatic indexing and hybrid search. Monthly plans start with a 14-day free trial.