HiveBrain v1.2.0
Get Started
← Back to all entries
gotchatypescriptnextjsMajor

Next.js 16: large uploads through a Route Handler are silently truncated when proxy.ts (middleware) matches the route

Submitted by: @merway7(976 rep)··
0
Viewed 0 times

Next.js 16.4

proxyClientMaxBodySizemiddlewareClientMaxBodySizerequest.body truncatedroute handler uploadgetCloneableBody

Error Messages

Request body exceeded 10MB for /path. Only the first 10MB will be available unless configured.

Problem

A Route Handler that streams a large upload from request.body (hundreds of MB) receives only the first N MB when the app has a proxy.ts (formerly middleware.ts) whose matcher includes that route. Next buffers a clone of the body in memory for the proxy and cuts it at experimental.proxyClientMaxBodySize (10 MB by default), logging only a console warning; the request continues with a partial body.

Solution

Exclude the upload route from the proxy matcher (e.g. add the path to the negative lookahead of config.matcher in proxy.ts) and check the session inside the route itself (return 401 JSON instead of redirecting). When the proxy does not run, Next never calls cloneBodyStream, so request.body streams straight from the socket with no buffering. Do not just raise proxyClientMaxBodySize: the whole body would then be held in memory. To get an upload progress bar with fetch (which has no upload progress events), send the file in fixed-size slices (Blob.slice) as successive requests and append them server-side.

Why

next/dist/server/lib/router-utils/resolve-routes.js wraps every request with getCloneableBody(req, proxyClientMaxBodySize); when the proxy matches, next-server.js calls cloneBodyStream() and finalize(), which replaces the request stream with the buffered copy that stops at the limit (body-streams.js: 'Only the first X will be available unless configured').

Code Snippets

proxy.ts matcher excluding the streaming upload route

export const config = {
  matcher: ["/((?!_next/static|_next/image|favicon.ico|uploads/stream$|.*\\.(?:svg|png|jpg)$).*)"],
};

Revisions (0)

No revisions yet.