remotion-dev/remotion · error · Error

The input is not a supported media file.

Error message

The input is not a supported media file.

What it means

Before decoding, separateVideoLayers wraps the input in a mediabunny Input and calls input.canRead(). If the source cannot be read as a supported media file (unrecognized/missing container or demuxer failure), this Error is thrown. It is the library's way of saying the src is not a media file mediabunny can demux (MP4/WebM etc.).

Source

Thrown at packages/video-matting/src/separate-video-layers.ts:253

const makeInput = (src: string | URL | Blob): Input => {
	const source =
		typeof src === 'string' || src instanceof URL
			? new UrlSource(src)
			: new BlobSource(src);

	return new Input({formats: ALL_FORMATS, source});
};

const probeVideoInput = async ({
	input,
	videoQuality,
}: {
	input: Input;
	videoQuality: Quality;
}): Promise<{videoTrack: InputVideoTrack; width: number; height: number}> => {
	if (!(await input.canRead())) {
		throw new Error('The input is not a supported media file.');
	}

	const videoTrack = await input.getPrimaryVideoTrack();
	if (videoTrack === null) {
		throw new Error('The input does not contain a video track.');
	}

	if (!(await videoTrack.canDecode())) {
		throw new Error('The primary video track cannot be decoded.');
	}

	const [width, height] = await Promise.all([
		videoTrack.getDisplayWidth(),
		videoTrack.getDisplayHeight(),
	]);
	if (
		!Number.isInteger(width) ||
		width <= 0 ||

View on GitHub (pinned to b2f4e34732)

Solutions

  1. Verify the URL/Blob resolves to a real, supported media file (open it in a browser tab or check Content-Type).
  2. Confirm the server serves the file with correct status and Content-Type (video/mp4, video/webm) and CORS headers if cross-origin.
  3. Check the file extension vs actual container with `file` (CLI) or the first bytes of the Blob.
  4. Re-encode the source into MP4 (H.264) or WebM (VP9) if it is in an unsupported container/codec.

Example fix

// before
const res = await separateVideoLayers({src: '/api/export?id=1'}); // returns HTML error page
// after
const response = await fetch('/api/export?id=1');
if (!response.headers.get('content-type')?.startsWith('video/')) {
  throw new Error('Endpoint did not return a video file');
}
await separateVideoLayers({src: response.url});
Defensive patterns

Strategy: validation

Validate before calling

const input = new Input({source: new UrlSource(src), formats: ALL_FORMATS});
if (!(await input.canRead())) {
  throw new Error(`Source is not a supported media file: ${src}`);
}

Try / catch

try {
  await separateVideoLayers({src});
} catch (e) {
  if (e instanceof Error && e.message.includes('not a supported media file')) {
    showUserError('Please provide an MP4 or WebM video file.');
  } else throw e;
}

Prevention

When it happens

Trigger: Passing a src string/URL/Blob that is not a media file (HTML error page, JSON, missing file served with 200, empty Blob), or a URL that fails to fetch, or a format mediabunny does not support (e.g. AVI, MKV with unsupported profiles).

Common situations: Server returns an HTML 404 page with status 200; dev proxy misroutes the media request; user uploads a file with .mp4 extension that is actually something else; CORS-blocked fetch yielding an opaque empty response; pointing at a WebM that is actually an audio-only stream container that can't be read.

Understand the failure class

Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.

Related errors


AI-assisted analysis of remotion-dev/remotion@b2f4e34732 (2026-09-09). Data as JSON: /api/errors/0d6427b436e1ab04. Report an issue: GitHub.