n8n Convert to File base64 video is corrupt: the data URI fix

The Convert to File node goes green. The binary item is there, roughly the size you expected. Then the next step fails: the upload is rejected, the player shows nothing, or your encoder comes back with moov atom not found. Nothing in the n8n execution log says anything went wrong, because as far as the node is concerned, nothing did.
Quick answer: The n8n Convert to File base64 operation writes a corrupt video when the string it receives is a data URI, becausedata:video/mp4;base64,is handed toBuffer.from()along with the payload and Node's decoder skips the invalid characters instead of erroring, which shifts the real bytes out of alignment (n8n issue #37612). Fix it by stripping the prefix in a Set or Code node with{{ $json.video.replace(/^data:[^;,]+;base64,/, '') }}before Convert to File, or upgrade to n8n@2.45.0 (released 2026-10-20, PRs #38383 and #38554) and re-add the node so you get the patched v1.2 version. The durable fix is to stop moving video bytes through n8n as base64 at all: hand the source URL to a processing API like FFmpeg Micro, poll the job, and download the finished file.
Why a shifted byte kills an MP4 but not a PNG
A data URI is two things glued together: an ASCII header and a base64 payload. The old Convert to File code passed the whole glued string to Buffer.from(str, 'base64'). Node's base64 decoder does not throw on characters outside the base64 alphabet. It skips them. So the header's characters are partly discarded and partly absorbed as valid alphabet characters, and the real payload starts decoding at the wrong offset. You get a buffer of plausible length holding bytes that are off by a few positions. Issue #37612 is the canonical report, and the write-up in PR #38383 notes the same code path also silently decoded plain text into mangled bytes.
Most reports you'll find are about images, which is misleading, because images and video fail differently. A PNG with a damaged header fails loudly: the preview in n8n is blank, you see it in two seconds. An MP4 is a box structure, and the first boxes are ftyp and moov. Destroy those and there is no partial render to tip you off. The file has a real size, it downloads, it uploads to storage, and the failure surfaces one or two nodes later in whatever tries to demux it. That's why this bug quietly produces dead videos in pipelines whose owners blame a flaky upload step.
Text-to-speech endpoints, image and video models, canvas exports and plenty of ordinary REST APIs return data URIs by default, so the shape repeats: base64 in, Convert to File, something downstream chokes.
Upgrading to 2.45.0 does not repair the node you already built
n8n@2.45.0 shipped on 2026-10-20 with the fix from PRs #38383 and #38554. The patched code strips the data-URI prefix before decoding, infers the MIME type from the URI when the node has none set, and rejects malformed padding and non-string input instead of writing garbage. Plain, unpadded, URL-safe and whitespace-wrapped base64, plus existing Buffer values, all keep working.
The detail that matters is in the PR body, not the release notes: the strict validation is gated to the new Convert to File v1.2, and existing v1 and v1.1 nodes keep the old permissive decode for backward compatibility. Upgrading your instance doesn't change a node you dropped into a workflow last month. To get the new behavior there, delete the Convert to File node and add a fresh one, which comes in at v1.2.
That gating cuts both ways. On a new v1.2 node, a payload that used to produce a quiet bad file now raises a descriptive NodeOperationError instead, and for plain-text input it points you at the Convert to Text File operation. If you rebuilt a workflow this week and it started erroring where it used to "work," the node did not break. It started telling the truth.
One more version note. n8n pushed 2.45.1 on Oct 21, 2.45.2 on Oct 22 and 2.45.3 on Oct 23. The 2.45.1 core fix (#41558) closes a queue-mode race where a worker could fail a job it never started, leaving the execution marked crashed with startedAt = null, triggered by a long synchronous node blocking the event loop. If you run queue mode and do heavy media work inside n8n, go to 2.45.1 or later. We covered the upgrade sequencing in n8n CVE October 2026: upgrade without breaking FFmpeg.
The two-minute fix if you can't upgrade today
A Set node in front of Convert to File solves this on any version. Add a field, assign the cleaned string, and point the node's Base64 Input Field at that field name.
{{ $json.video.replace(/^data:[^;,]+;base64,/, '') }}
If the source is inconsistent, or you want the padding check, use a Code node instead. Unpadded base64 is legal and the patched node accepts it, but some upstream services truncate rather than omit padding, and a truncated string decodes short:
for (const item of $input.all()) {
let b64 = String(item.json.video)
.replace(/^data:[^;,]+;base64,/, '')
.replace(/\s+/g, '');
const remainder = b64.length % 4;
if (remainder === 1) throw new Error('Truncated base64: length % 4 === 1');
if (remainder) b64 += '='.repeat(4 - remainder);
item.json.videoClean = b64;
}
return $input.all();
The Base64 Input Field on the Convert to File node takes the name of the field, like videoClean, not an expression that resolves to the base64 value. And set a filename with the right extension on the node, because an MP4 named data will confuse the next service even when the bytes are perfect.
Leave the Set-node strip in place after you upgrade. Stripping a prefix that's already gone is a no-op against the regex.
The pattern where none of this can happen
Base64 inflates a payload by about 33%, so a 200 MB MP4 arrives as a roughly 267 MB JSON string, and it lives in the item's JSON, not in binary storage. Setting N8N_DEFAULT_BINARY_DATA_MODE=filesystem moves binary items to disk, but it does nothing for a base64 string in $json. Builders have reported Convert to File falling over around 4.5 MB of base64 in n8n Cloud, with errors like "The value in [field] is not set" and "Operation not permitted" (issue #17176). For video, the patched node mostly buys you a correct file your instance still cannot hold.
So the real fix is upstream of the node: don't put the bytes in n8n. Give the processing API a URL, poll the job, and download the output at the end, or hand the output URL straight to the next service.
| Base64 round-trip | URL in, URL out | |
|---|---|---|
| Peak memory in n8n | ~267 MB string for a 200 MB MP4 | a few KB of JSON |
| Practical size ceiling | ~4.5 MB of base64 on n8n Cloud | the API's input cap (1,024 MB on Starter) |
| Failure mode | silent corruption on old nodes, hard error on v1.2 | HTTP status you can branch on |
| Nodes involved | HTTP Request, Set, Convert to File, Write File | HTTP Request, Wait, IF |
In n8n the chain is four nodes. An HTTP Request node posts the source URL to POST https://api.ffmpeg-micro.com/v1/transcodes with a body like {"inputs":[{"url":"https://.../source.mp4"}],"outputFormat":"mp4","preset":{"quality":"medium","resolution":"1080p"}} and gets back a job id. A Wait node pauses a few seconds. A second HTTP Request polls GET /v1/transcodes/{id} until status is completed. Then GET /v1/transcodes/{id}/download returns a signed URL you can pass to Google Drive, an upload node, or anything else. More than 300 builders already run FFmpeg Micro from Make or n8n this way, and the n8n Cloud walkthrough ships the workflow JSON, including the sub-workflow that handles polling. The free tier is 200 tokens at sign-up, about 33 minutes of video, no card.
If you landed here from the other direction, because the Execute Command node is gone or FFmpeg isn't on the box, Why n8n says "No usable ffmpeg was found" covers that half of the problem.
Pitfalls worth knowing before you debug further
Out-of-memory and corrupt-bytes failures both present as "the next node failed," and telling them apart saves an hour. Check the n8n execution: if the workflow died partway with no output item, or the container restarted, it's memory. If the Convert to File node completed with a binary item of a sensible size and something later rejected it, it's bytes. Run ffprobe on the downloaded file. A byte-shifted MP4 reports moov atom not found or Invalid data found when processing input, while a truncated one usually probes fine and fails at the end of playback.
The other traps are smaller. A node that downloads with "Response Format: File" never produces base64, so if you're reaching for Convert to File to undo something, check whether you need it. The Compression node's decompression cap dropped to 256 MiB in n8n 3.0, so zipping a video to dodge a size limit will hit a different wall. n8n 2.45.0 also added referencing binary data from any earlier node and a binary entry type on the Set node, so the dummy Merge nodes most video tutorials tell you to add are no longer needed.
FAQ
Does upgrading to n8n 2.45.0 fix my existing workflow?
Upgrading n8n to 2.45.0 does not change a Convert to File node you already built. The strict base64 validation and data-URI handling are enabled only on the node's new v1.2 version, and your existing v1 or v1.1 node keeps decoding permissively. Delete the node and add a new one to pick up the fix, or keep a Set node in front of it stripping the prefix.
Why does my image come through fine but my MP4 won't play?
The same byte shift damages both files, but a PNG fails visibly at the first preview while an MP4 loses its ftyp and moov header boxes and simply refuses to open. The video is also more likely to be handed to a storage or publishing step that accepts any bytes, so the error surfaces two nodes away from the real cause.
What error does the patched Convert to File node show now?
A v1.2 Convert to File node raises a NodeOperationError describing the invalid base64 rather than writing a file, and when the input is plain text it suggests the Convert to Text File operation instead. Payloads that silently produced broken media before now stop the execution. That's the intended change.
Is unpadded or URL-safe base64 still supported?
Unpadded, URL-safe and whitespace-wrapped base64 all still decode correctly on the patched node, per PR #38554. What the node now rejects is malformed padding and non-string input. If your string's length modulo 4 equals 1, the upstream service truncated it and no amount of padding will recover the missing bytes.
How big a video can I realistically push through Convert to File?
Convert to File on n8n Cloud has been reported failing around 4.5 MB of base64, which is roughly a 3.4 MB source file after the 33% encoding overhead. Self-hosted instances go further but hold the whole string in the JSON item, so a 200 MB video means a ~267 MB string in memory before anything decodes it.
Skipping the base64 hop entirely takes about as long as adding the Set node did. The FFmpeg Micro quickstart walks the presigned upload, transcode, poll and download flow with a temporary API key, so you can run the URL-in, URL-out version before you finish the upgrade.
Note on sourcing: I couldn't open GitHub to verify the claim that strict validation is gated to Convert to File v1.2 while v1 and v1.1 keep the old decode (WebFetch permission wasn't granted). It's asserted twice here, in the "Upgrading to 2.45.0" section and the first FAQ, so confirm it on PR #38554 before this ships.
About Javid Jamae
Founder & CEO at FFmpeg Micro
Javid is a software engineer, author, and entrepreneur with over 25 years of professional software development experience across enterprise, startup, and consulting environments. He founded FFmpeg Micro to make video processing accessible to developers through a simple, automation-first REST API.
You might also like

n8n 3.0 breaking changes: fix your video step in this order
The n8n 3.0 breaking changes that kill FFmpeg steps: the 60-second task timeout, Docker-only self-hosting, Compression caps, and removed nodes, in fix order.

n8n 3.0 breaking changes kill your FFmpeg step: what to change
n8n 3.0 breaking changes that kill a self-hosted FFmpeg workflow: removed binary file nodes, a 60-second runner timeout, a 256 MiB cap, and what to change.

Why n8n says "No usable ffmpeg was found" and what to do about it
"No usable ffmpeg was found" in n8n means the server has no FFmpeg binary, and n8n's installer makes it impossible for a community node to ship one. Three real fixes.
Ready to process videos at scale?
Start using FFmpeg Micro's simple API today. No infrastructure required.
Get Started Free