Receiving an Uploaded File in n8n: the Webhook Node vs. multipart/form-data
By Clément Lacaille (Tech-Bharat) · Published 22 September 2026 · 5 min read · how we build and test
Complete FlowKit Bundle — €269
12 ready-to-import n8n workflows, setup guide in French, 14-day guarantee
It's a familiar scenario: an HTML form with an <input type="file"> field posts to an n8n Webhook, the execution shows up fine in the editor — but the node's Binary tab stays stubbornly empty, or the file appears under an unexpected key like file0. Nothing is broken server-side: it's the mechanics of multipart/form-data, different from a plain JSON body, that aren't configured the way n8n expects. This guide covers how the Webhook node actually receives a file, exactly what the Binary Property field does, and the traps behind 90% of "empty file" reports on n8n.
JSON vs. multipart/form-data: two different mechanics
A typical n8n Webhook receives a JSON body (Content-Type: application/json), read directly into $json. A file upload from an HTML <form> or a JavaScript FormData() object takes a different path: the request is encoded as multipart/form-data, a format that splits the body into several blocks separated by a boundary — one block per text field, one block per binary file, each with its own Content-Disposition: form-data; name="..." header.
n8n tells the two apart automatically: the form's text fields land in $json.body, and each file lands in $binary, under a key that by default mirrors the name of the matching HTML <input>. A form with <input type="file" name="id_document"> will therefore produce a $binary.id_document accessible in downstream nodes — provided the request is actually sent as multipart, not as JSON with the file hand-encoded as base64 (a common mistake when the form is built with fetch() without going through a FormData object).
Binary Property: useful for one file, tricky for several
In the Webhook node's options, the Binary Property field lets you force the key under which the received file is exposed in $binary, instead of relying on the HTML field name. That's convenient for a simple form with a single file field whose name may vary.
The trap shows up with several file fields in the same form (for example id_document and proof_of_address for an onboarding case). If you set Binary Property, n8n groups every received file and renames them generically to file0, file1, etc. — you lose the link between each file and its original field, a behavior reported repeatedly on the n8n community forum. The right move in that case: leave Binary Property empty. Each file then stays available under its exact HTML field name ($binary.id_document, $binary.proof_of_address), with no extra handling needed.
Test before wiring up a real form
Before connecting a production form, validate the setup with curl, which builds a correct multipart/form-data request with no extra effort:
curl -X POST https://your-instance.n8n.cloud/webhook/upload-test \
-F "id_document=@invoice.pdf" \
-F "comment=Test upload"
The Webhook node should then show comment in $json.body and id_document in the Binary tab, with its size, MIME type (fileType) and original filename (fileName) already filled in by n8n. Our guide to testing n8n webhooks locally shows how to reproduce this test without exposing a public URL, using the editor's test URL.
Common pitfalls and error messages
- Empty file despite a request that looks correct: check the browser's Network tab to confirm the
Content-Typesent is actuallymultipart/form-data; boundary=..., notapplication/json. A JavaScriptFormData()object builds thisContent-Typeautomatically — never set it manually on your request's headers, or theboundarydisappears and n8n can no longer split the body. - 413 error or a truncated file: the file exceeds
N8N_FORMDATA_FILE_SIZE_MAX(200 MiB by default in self-hosted) or your n8n Cloud plan's specific limit. Our guide to large files and binary data covers this variable and the related memory behavior; our dedicated article on the 413 error covers the case of plain JSON payloads. - Signature verification failing after an upload: if your webhook also needs to verify an HMAC signature (a Stripe or GitHub webhook, for instance), the raw body needed for the signature calculation generally isn't available the same way in multipart as it is in JSON. That scenario is beyond a simple form; our guide to securing n8n webhooks covers the options for this more advanced case.
What to do with the file once received
Once the binary is available under its $binary key, it flows like any other n8n file: an HTTP Request node can relay it to Google Drive, S3 or a CRM, a dedicated node can archive it, or — a common case for a client file — it can feed a document-ingestion pipeline directly. That's exactly what the PDF Ingestion to Supabase pgvector workflow does in the RAG Assistant Pack (€119): a client drops a PDF through a web form, and the document is chunked, embedded and made searchable with no manual step. The same principle applies to the attachments of an audit case, handled by the logging workflow in the Compliance & Audit Pack (€149).
Before processing the file, validate it instead of trusting it: the actual MIME type ($binary.id_document.fileType), the expected extension, a reasonable size. A recent study by Chen, Li, Pan, Lu, Chen and Ji, "URadar: Discovering Unrestricted File Upload Vulnerabilities via Adaptive Dynamic Testing" (IEEE Transactions on Information Forensics and Security, 2023 — see the study), uncovered dozens of code-execution vulnerabilities exploitable through insufficiently controlled upload endpoints, in real-world web applications. The lesson transposes directly to a publicly exposed n8n workflow: never execute, interpret, or serve back as-is a file received through a webhook without checking its actual type, and restrict accepted extensions to what the workflow can genuinely handle.
Webhook or Form Trigger: which to pick
If the form doesn't need to exist anywhere outside n8n, the Form Trigger node makes handling an upload noticeably simpler: form rendering, field validation and binary handling are all native, with no manual multipart configuration. The Webhook remains the right choice whenever the file comes from a form or application that already exists and that you don't control from the n8n editor — a marketing site, an internal application, or the kind of integration covered in our complete guide to the Webhook node.
Key takeaways
A file upload to an n8n Webhook follows mechanics quite distinct from a plain JSON webhook: multipart/form-data separates text fields from files, and each file lands in $binary under its HTML field name — unless you force a single key via Binary Property, which breaks that mapping as soon as there's more than one file. Always test with curl -F before wiring up a real form, watch the size limits, and validate the received file (actual type, extension, size) before passing it further down the workflow.
FAQ
Frequently asked questions
Why does my n8n Webhook node's Binary tab stay empty after a file upload?
The most common cause: the form isn't actually sending the request as multipart/form-data (for example a fetch() call that posts JSON with the file base64-encoded instead of a real FormData object), or the request's Content-Type doesn't match what n8n expects. Check the browser's Network tab to confirm the request's Content-Type starts with multipart/form-data; boundary=... and that the body contains one block per field, including the file.
What does the Webhook node's "Binary Property" field actually do?
It renames the received file under a single fixed key in $binary, which is handy when the form only ever sends one file under a variable field name. But if your form sends several files under different field names (e.g. id_document and proof_of_address), setting this field groups and renames them to file0, file1... Leave it empty to keep each file's original HTML field name.
Should the received file be validated before processing?
Yes, always: the binary's declared MIME type (fileType in $binary), its extension, and its size. Never trust the extension alone or the Content-Type the client declared, since both can be forged — that is precisely the mechanism documented by security research into unrestricted file upload vulnerabilities.
Is the Form Trigger node simpler than the Webhook for receiving a file?
Yes, for a form that only needs to exist inside n8n: Form Trigger natively handles form rendering, field validation and file upload without any manual multipart configuration. The Webhook remains the right choice whenever the file comes from a form or application you don't control from the n8n editor.