Link to the code that reproduces this issue
https://github.com/Str1ckl4nd/next-edge-server-actions-body-limit-repro
To Reproduce
npm install
npm run make-payload
npm run dev
Then:
- Open
http://localhost:3000/node.
- Upload the generated
payload.bin file and submit the form.
- Open
http://localhost:3000/edge.
- Upload the same
payload.bin file and submit the form.
Expected: both runtimes reject the 3 MiB upload because the Server Actions body limit is 2mb.
Observed: the Node runtime rejects the request with Body exceeded 2mb limit., while the Edge runtime accepts the same upload and logs File name: payload.bin size: 3145728.
Current vs. Expected behavior
Current behavior:
The Node runtime Server Action rejects the 3 MiB multipart upload because experimental.serverActions.bodySizeLimit is set to 2mb. The observed error is:
The equivalent Edge runtime Server Action accepts the same 3 MiB multipart upload and executes the action. The observed server log is:
File name: payload.bin size: 3145728
Expected behavior:
Both runtimes should enforce the configured Server Actions body limit consistently. With experimental.serverActions.bodySizeLimit: '2mb', a 3 MiB multipart Server Action request should be rejected in both the Node and Edge runtimes.
Why this appears to happen:
In v16.3.0-canary.67, the Edge runtime multipart Server Action path calls req.request.formData() directly:
https://github.com/vercel/next.js/blob/v16.3.0-canary.67/packages/next/src/server/app-render/action-handler.ts#L771-L773
The Node runtime path calculates bodySizeLimitBytes, applies sizeLimitTransform, and raises the Body exceeded ... limit error when the stream exceeds the configured limit:
https://github.com/vercel/next.js/blob/v16.3.0-canary.67/packages/next/src/server/app-render/action-handler.ts#L901-L923
For multipart action requests, the Node path then pipes the request body through the size-limiting transform before decoding the action payload:
https://github.com/vercel/next.js/blob/v16.3.0-canary.67/packages/next/src/server/app-render/action-handler.ts#L953-L958
The result is a runtime-specific limit bypass for multipart Server Action form submissions. An application that relies on serverActions.bodySizeLimit to bound request memory/work gets the configured limit in Node, but the Edge action path can still parse and execute a larger multipart body.
Provide environment information
Operating System:
Platform: linux
Binaries:
Node: 22.x
npm: 10.x
Relevant Packages:
next: 16.3.0-canary.67
react: 19.2.7
react-dom: 19.2.7
Next.js Config:
experimental.serverActions.bodySizeLimit: 2mb
Which area(s) are affected? (Select all that apply)
Server Actions
Which stage(s) are affected? (Select all that apply)
next dev (local)
Additional context
No response
Link to the code that reproduces this issue
https://github.com/Str1ckl4nd/next-edge-server-actions-body-limit-repro
To Reproduce
Then:
http://localhost:3000/node.payload.binfile and submit the form.http://localhost:3000/edge.payload.binfile and submit the form.Expected: both runtimes reject the 3 MiB upload because the Server Actions body limit is
2mb.Observed: the Node runtime rejects the request with
Body exceeded 2mb limit., while the Edge runtime accepts the same upload and logsFile name: payload.bin size: 3145728.Current vs. Expected behavior
Current behavior:
The Node runtime Server Action rejects the 3 MiB multipart upload because
experimental.serverActions.bodySizeLimitis set to2mb. The observed error is:The equivalent Edge runtime Server Action accepts the same 3 MiB multipart upload and executes the action. The observed server log is:
Expected behavior:
Both runtimes should enforce the configured Server Actions body limit consistently. With
experimental.serverActions.bodySizeLimit: '2mb', a 3 MiB multipart Server Action request should be rejected in both the Node and Edge runtimes.Why this appears to happen:
In
v16.3.0-canary.67, the Edge runtime multipart Server Action path callsreq.request.formData()directly:https://github.com/vercel/next.js/blob/v16.3.0-canary.67/packages/next/src/server/app-render/action-handler.ts#L771-L773
The Node runtime path calculates
bodySizeLimitBytes, appliessizeLimitTransform, and raises theBody exceeded ... limiterror when the stream exceeds the configured limit:https://github.com/vercel/next.js/blob/v16.3.0-canary.67/packages/next/src/server/app-render/action-handler.ts#L901-L923
For multipart action requests, the Node path then pipes the request body through the size-limiting transform before decoding the action payload:
https://github.com/vercel/next.js/blob/v16.3.0-canary.67/packages/next/src/server/app-render/action-handler.ts#L953-L958
The result is a runtime-specific limit bypass for multipart Server Action form submissions. An application that relies on
serverActions.bodySizeLimitto bound request memory/work gets the configured limit in Node, but the Edge action path can still parse and execute a larger multipart body.Provide environment information
Which area(s) are affected? (Select all that apply)
Server Actions
Which stage(s) are affected? (Select all that apply)
next dev (local)
Additional context
No response