Admin panel always sends multipart/form-data even when no file upload is present in the form
Nobody has claimed this yet.
Assessment
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Newbie friendliness
- 72/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Quiet
- Tech stack
- react, typescript
- Domain
- frontend
Research direction
Start with @payloadcms/ui/dist/elements/SaveDraftButton/index.js, PublishButton/index.js, and Autosave/index.js, tracing how each request payload and content type are constructed. Verify the JSON-only collection workflow and a workflow containing File or Blob data; done means JSON-only submissions use application/json while file uploads continue to use multipart/form-data.
Written by the indexing model from the issue text.
Description
Describe the Bug
The admin panel unconditionally sends all PATCH/POST requests (save, autosave, publish, save draft) as multipart/form-data, even when the request payload contains only JSON data and no file is being uploaded.
Per HTTP semantics, multipart/form-data is intended for requests that include binary file data. When the payload is purely JSON (no File or Blob objects in the FormData), the request should use application/json. Sending JSON-only data wrapped in multipart encoding is unnecessary overhead and triggers false positives in standard WAF configurations.
Verified behavior:
- Exact same JSON body sent as application/json to the same endpoint: 200 OK
- Same JSON body wrapped in multipart/form-data to the same endpoint: 403 blocked by WAF
The issue is that the admin panel always constructs a FormData object and appends the JSON as a field named "_payload", regardless of whether any File objects are present.
The affected components in @payloadcms/ui/dist/elements/ are:
- SaveDraftButton/index.js
- PublishButton/index.js
- Autosave/index.js
Expected behavior: When the form submission does not include any File or Blob objects, the request should be sent as application/json with the JSON body directly, not wrapped in multipart/form-data.
Link to the code that reproduces this issue
https://github.com/payloadcms/payload/tree/main (reproducible with any collection behind Cloudflare Enterprise WAF)
Reproduction Steps
- Create a collection with multiple fields (no upload/image fields)
- Deploy behind Cloudflare Enterprise with Managed Ruleset active
- Open admin panel, create or edit a document, click Save
- The browser sends a PATCH request with content-type: multipart/form-data
- Cloudflare WAF blocks the request with 403 (rule 6179ae15870a4bb7b2d480d4843b323c, score-based)
- Send the exact same body manually with content-type: application/json — it passes with 200
Which area(s) are affected?
area: ui
Environment Info
Binaries:
Node: 24.14.0
npm: 11.9.0
Yarn: N/A
pnpm: 9.7.0
Relevant Packages:
payload: 3.87.0
next: 15.3.9
@payloadcms/db-mongodb: 3.87.0
@payloadcms/db-postgres: 3.87.0
@payloadcms/drizzle: 3.87.0
@payloadcms/email-nodemailer: 3.87.0
@payloadcms/graphql: 3.87.0
@payloadcms/live-preview: 3.87.0
@payloadcms/live-preview-react: 3.87.0
@payloadcms/next/utilities: 3.87.0
@payloadcms/payload-cloud: 3.87.0
@payloadcms/plugin-cloud-storage: 3.87.0
@payloadcms/plugin-form-builder: 3.87.0
@payloadcms/plugin-nested-docs: 3.87.0
@payloadcms/plugin-redirects: 3.87.0
@payloadcms/plugin-search: 3.87.0
@payloadcms/plugin-seo: 3.87.0
@payloadcms/richtext-lexical: 3.87.0
@payloadcms/storage-s3: 3.87.0
@payloadcms/translations: 3.87.0
@payloadcms/ui/shared: 3.87.0
react: 19.1.0
react-dom: 19.1.0
Operating System:
Platform: darwin
Arch: arm64
Version: Darwin Kernel Version 25.3.0: Wed Jan 28 20:54:46 PST 2026; root:xnu-12377.91.3~2/RELEASE_ARM64_T6000
Available memory (MB): 32768
Available CPU cores: 10
- Dominant language
- TypeScript
- Stars
- 44.8k
- Forks
- 4.2k
- Avg merge
- 2d 21h
- Merged PRs (30d)
- 53
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from payloadcms/payload
-
area: ui Bug status: needs-triage v3
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
payloadcms/payload#18215 · 1 comment ·
-
Bug
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
payloadcms/payload#18163 ·
-
Bug
Difficulty 2/5 1-3 hours Newbie friendliness 85/100
payloadcms/payload#18161 ·
-
area: core Bug
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
payloadcms/payload#18072 ·
-
Bug
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
payloadcms/payload#18067 · 1 comment ·
All issues in payloadcms/payload
Similar issues
-
clawsweeper:fix-shape-clear clawsweeper:queueable-fix clawsweeper:source-repro impact:ux-friction issue-rating: 🦞 diamond lobster no-stale P3
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
community first-timers-only good first issue hacktoberfest help wanted low hanging fruit up-for-grabs
Difficulty 1/5 Under an hour Newbie friendliness 76/100
-
code-quality refactoring
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
github/gh-aw-firewall#8816 ·
-
integration:quickjs org:external priority:backlog topic:code-interpreter topic:middleware type:feature
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
langchain-ai/deepagents#6450 ·
-
Difficulty 1/5 Under an hour Newbie friendliness 88/100
vercel/react-tweet#225 ·