formData with app router: Upload error: TypeError: Failed to parse body as FormData.
Link to the code that reproduces this issue
https://codesandbox.io/p/sandbox/twilight-flower-v6pl9s
To Reproduce
i am uploading a file using axios in a client side component in this way:
const options: AxiosRequestConfig = {
headers: { 'Content-Type': 'multipart/form-data' }
};
const { data } = await axios.post<{ success: boolean; }>(
'/api/upload',
formData,
options
);
in the /api/upload route i have the following code:
export async function POST(request: NextRequest) {
try {
console.log('in post');
let formData = await request.formData();
console.log('formData', formData);
const file = formData.get('file') as File;
} catch (error) {
console.error('Upload error:', error);
return NextResponse.json(
{ error: 'Failed to upload file' },
{ status: 500 }
);
}
}
if the file is <~2GB everythings is working, the formData is returned with the correct values, otherwise if the file is bigger i get the following output:
Upload error: TypeError: Failed to parse body as FormData.
at node:internal/deps/undici/undici:5668:27
at successSteps (node:internal/deps/undici/undici:5712:27)
at fullyReadBody (node:internal/deps/undici/undici:4609:9)
at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
at async consumeBody (node:internal/deps/undici/undici:5721:7)
at async POST (/Users/539hex/dev/deft.cx/.next/server/chunks/_bc0f62._.js:282:24)
at async /Users/539hex/dev/deft.cx/node_modules/next/dist/compiled/next-server/app-route.runtime.dev.js:6:55831
at async eO.execute (/Users/539hex/dev/deft.cx/node_modules/next/dist/compiled/next-server/app-route.runtime.dev.js:6:46527)
at async eO.handle (/Users/539hex/dev/deft.cx/node_modules/next/dist/compiled/next-server/app-route.runtime.dev.js:6:57165)
at async doRender (/Users/539hex/dev/deft.cx/node_modules/next/dist/server/base-server.js:1353:42)
at async cacheEntry.responseCache.get.routeKind (/Users/539hex/dev/deft.cx/node_modules/next/dist/server/base-server.js:1575:28)
at async DevServer.renderToResponseWithComponentsImpl (/Users/539hex/dev/deft.cx/node_modules/next/dist/server/base-server.js:1483:28)
at async DevServer.renderPageComponent (/Users/539hex/dev/deft.cx/node_modules/next/dist/server/base-server.js:1911:24)
at async DevServer.renderToResponseImpl (/Users/539hex/dev/deft.cx/node_modules/next/dist/server/base-server.js:1949:32)
at async DevServer.pipeImpl (/Users/539hex/dev/deft.cx/node_modules/next/dist/server/base-server.js:921:25)
at async NextNodeServer.handleCatchallRenderRequest (/Users/539hex/dev/deft.cx/node_modules/next/dist/server/next-server.js:272:17)
at async DevServer.handleRequestImpl (/Users/539hex/dev/deft.cx/node_modules/next/dist/server/base-server.js:817:17)
at async /Users/539hex/dev/deft.cx/node_modules/next/dist/server/dev/next-dev-server.js:339:20
at async Span.traceAsyncFn (/Users/539hex/dev/deft.cx/node_modules/next/dist/trace/trace.js:154:20)
at async DevServer.handleRequest (/Users/539hex/dev/deft.cx/node_modules/next/dist/server/dev/next-dev-server.js:336:24)
at async invokeRender (/Users/539hex/dev/deft.cx/node_modules/next/dist/server/lib/router-server.js:173:21)
at async handleRequest (/Users/539hex/dev/deft.cx/node_modules/next/dist/server/lib/router-server.js:350:24)
at async requestHandlerImpl (/Users/539hex/dev/deft.cx/node_modules/next/dist/server/lib/router-server.js:374:13)
at async Server.requestListener (/Users/539hex/dev/deft.cx/node_modules/next/dist/server/lib/start-server.js:141:13)
POST /api/upload 500 in 9203ms
Current vs. Expected behavior
I expect always to have the formData returned despite the file size
Provide environment information
Operating System:
Platform: darwin
Arch: arm64
Version: Darwin Kernel Version 24.1.0: Thu Oct 10 21:03:11 PDT 2024; root:xnu-11215.41.3~2/RELEASE_ARM64_T6020
Available memory (MB): 32768
Available CPU cores: 12
Binaries:
Node: 23.3.0
npm: 10.9.0
Yarn: 1.22.22
pnpm: 9.12.1
Relevant Packages:
next: 14.2.18 // An outdated version detected (latest is 15.0.3), upgrade is highly recommended!
eslint-config-next: N/A
react: 18.3.1
react-dom: 18.3.1
typescript: 5.6.2
Next.js Config:
output: N/A
⚠ An outdated version detected (latest is 15.0.3), upgrade is highly recommended!
Please try the latest canary version (`npm install next@canary`) to confirm the issue still exists before creating a new issue.
Read more - https://nextjs.org/docs/messages/opening-an-issue
Which area(s) are affected? (Select all that apply)
Not sure
Which stage(s) are affected? (Select all that apply)
next dev (local)
Additional context
i tried also to update to next 15.0.3 and i have the same exact issue.
Possibly related? https://github.com/nodejs/undici/issues/3676
Yes it might be related
Are you able to downgrade Node.js to the 18-20 range, and test?
@icyJoseph i just tested with Node 18.20.5 and things are getting even stranger.
If i upload a file <2GB everythings is working as before, if the file is >2GB for example 2.65GB i am not getting any exception but the process will stuck right after the let formData = await request.formData(); and will hang forever without any message. If the file is even bigger (4.32GB) i get the following output
in post
Upload error: RangeError: offset is out of bounds
at Buffer.set (<anonymous>)
at BufferList.concat (node:internal/streams/buffer_list:72:7)
at fromList (node:internal/streams/readable:1373:26)
at Readable.read (node:internal/streams/readable:553:11)
at createAsyncIterator (node:internal/streams/readable:1163:54)
at createAsyncIterator.next (<anonymous>)
at Object.pull (node:internal/deps/undici/undici:792:52)
at ensureIsPromise (node:internal/webstreams/util:192:19)
at readableStreamDefaultControllerCallPullIfNeeded (node:internal/webstreams/readablestream:2250:5)
at node:internal/webstreams/readablestream:2341:7
POST /api/upload 500 in 721ms
Before I dive into this further, does it happen with simple fetch?
I suspect there's some Buffer allocation going on, https://stackoverflow.com/a/8974841, but it is just an early guess...
Same issue using native fetch.
Looks like the new node release ( 23.3.0 ) increased the buffer to 8192 TB, the 18.20.5 got it capped at 4 GB.
Still the issue is present in both versions.
➜ ~ node
Welcome to Node.js v23.3.0.
Type ".help" for more information.
> (require('buffer').constants.MAX_LENGTH + 1) / 2**30
8388608
>
➜ ~ node
Welcome to Node.js v18.20.5.
Type ".help" for more information.
> (require('buffer').constants.MAX_LENGTH + 1) / 2**30
4.000000000931323
>
Still the same issue with the latest node 23.4.0
Edit by maintainer bot: Comment was automatically minimized because it was considered unhelpful. (If you think this was by mistake, let us know). Please only comment if it adds context to the issue. If you want to express that you have the same problem, use the upvote 👍 on the issue description or subscribe to the issue for updates. Thanks!
I am experiencing the same issue with our React Native project. I have already tried running it with a normal Bun server, and React Native is working fine. Additionally, I have tested with different Node versions (v20.13.1 and v22.2.0), but the issue persists.
Interestingly, the functionality works fine when tested with Insomnia. Are there any logs or debugging steps I can help with? @icyJoseph
Update as of Node 24.0.2 - still the same issue
Unhandled error in POST /upload: [TypeError: Failed to parse body as FormData.] { [cause]: [TypeError: expected CRLF] }
some useful refs https://philna.sh/blog/2025/01/14/troubles-with-multipart-form-data-fetch-node-js/
@icyJoseph
Thanks for the link @539hex , informative
I was seeing this issue on node 22, then upgraded to node v24.4.1, and got this stack trace:
TypeError: Failed to parse body as FormData.
at parsingError (node:internal/deps/undici/undici:5914:14)
at multipartFormDataParser (node:internal/deps/undici/undici:5688:15)
... 3 lines matching cause stack trace ...
at process.processTicksAndRejections (node:internal/process/task_queues:105:5) {
[cause]: TypeError: missing boundary in content-type header
My particular app is a sveltekit app.
However, sending multipart/form-data via an html form element like: <form enctype="multipart/form-data"> worked.
It was only once I switched to submitting the data via a fetch call that I started receiving "Failed to parse body as FormData" errors...
I'm facing a similar issue here. If someone makes a POST request to my app with Content-Type: multipart/form-data and a request body containing quotes, e.g.:
"formdata":"d"
I get a 500 back from next and the following in the logs:
TypeError: Failed to parse body as FormData.
at parsingError (node:internal/deps/undici/undici:6114:14)
at parseMultipartFormDataHeaders (node:internal/deps/undici/undici:6058:17)
... 4 lines matching cause stack trace ...
at process.processTicksAndRejections (node:internal/process/task_queues:103:5) {
page: '/encode_image',
[cause]: TypeError: expected CRLF
I never actually hit any handlers / middleware, and the path being requested does not exist.
If I try this with node 18, I get a 200, but on the latest node 22, 24, 25 I get this error.
Well looks like the upstream fix https://github.com/nodejs/undici/issues/3676 didn't do the trick right? 🤔
@icyJoseph Correct. I have added logging to confirm the undici version (using process.versions) and I was on 7.16.0 which should contain that fix.
I've had a look at the relevant undici code and I'm pretty sure it's throwing here. From a next.js side, are we catching that error? If the caller sends us an invalid body, it seems we should catch a failed parse and return a 4xx.
Hi @MDUK0001. This issue started to appear for us when bumping to 15.4.8. I can consistently reproduce the issue with 15.4.8 and consistently not with 15.4.7. Which is problematic since 15.4.8 fixes a critical CVE.
Edit: 15.5.7 and 16.0.7 have the issue as well
What issue exactly? @dispix - I have been able to repro with 16.0.6 and 16.0.7, that uploading to a Route Handler, 2gb+ fails. It is a Node.js issue, or at least that's what the evidence is suggesting so far? Could you explain a bit more of your setup.
Our issues started yesterday, after upgrading from [email protected] to [email protected]. Uploading a file even 10Mb fails. I'm not sure this is size related. Here's the error:
error: {
"type": "TypeError",
"message": "Failed to parse body as FormData.: expected boundary after body",
"stack":
TypeError: Failed to parse body as FormData.
at parsingError (node:internal/deps/undici/undici:6114:14)
at multipartFormDataParser (node:internal/deps/undici/undici:5923:19)
at node:internal/deps/undici/undici:6364:34
at successSteps (node:internal/deps/undici/undici:6414:27)
at readAllBytes (node:internal/deps/undici/undici:5380:13)
at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
caused by: TypeError: expected boundary after body
at parsingError (node:internal/deps/undici/undici:6114:74)
at multipartFormDataParser (node:internal/deps/undici/undici:5923:19)
at node:internal/deps/undici/undici:6364:34
at successSteps (node:internal/deps/undici/undici:6414:27)
at readAllBytes (node:internal/deps/undici/undici:5380:13)
at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
}
POST /api/library/upload 500 in 71ms (compile: 3ms, proxy.ts: 54ms, render: 14ms)
We can see it's indeed coming from undici, however using [email protected] doesn't solve the issue. Here's what process.versions shows:
{
node: '24.11.0',
acorn: '8.15.0',
ada: '3.3.0',
amaro: '1.1.4',
ares: '1.34.5',
brotli: '1.1.0',
cjs_module_lexer: '2.1.0',
cldr: '47.0',
icu: '77.1',
llhttp: '9.3.0',
modules: '137',
napi: '10',
nbytes: '0.1.1',
ncrypto: '0.0.1',
nghttp2: '1.66.0',
openssl: '3.5.4',
simdjson: '3.13.0',
simdutf: '6.4.0',
sqlite: '3.50.4',
tz: '2025b',
undici: '7.16.0',
unicode: '16.0',
uv: '1.51.0',
uvwasi: '0.0.23',
v8: '13.6.233.10-node.28',
zlib: '1.3.1-470d3a2',
zstd: '1.5.7'
}
That often happens when you set the content type manually. fetch/axios recognize the body type and generate the content type header with the boundary and all (of course, this is likely not your issue, but let's start there) - any chance you could make a quick create-next-app showing the problem?
@icyJoseph I've managed to reproduce my issue with an unmodified create-next-app and node 24.8.0. Steps:
-
npx [email protected] formdata-repro -
cd formdata-repo -
npm run dev -
curl --request POST \ --url http://localhost:3000/ \ --header 'Content-Type: multipart/form-data' \ --data-raw '"formdata":"d"'
Output (from next server logs):
⨯ TypeError: Failed to parse body as FormData.
at ignore-listed frames {
[cause]: TypeError: missing boundary in content-type header
at ignore-listed frames
}
⨯ TypeError: Failed to parse body as FormData.
at ignore-listed frames {
page: '/',
[cause]: TypeError: missing boundary in content-type header
at ignore-listed frames
}
POST / 500 in 25ms (compile: 17ms, render: 7ms)
I'd expect to be able to handle this error, or have next return a 400. Adding an error.tsx or global-error.tsx doesn't change the behaviour.