remotion-dev/remotion · error · MediaPlaybackError

The browser threw an error

Error message

The browser threw an error

What it means

Thrown by VideoForRendering's HTMLMediaElement 'error' event listener when the browser fires an error event on a <video> during server-side rendering but the element's `.error` property is null/undefined (so no detailed code or message is available). It is the fallback branch of the errorHandler: when `current?.error` is falsy, Remotion cannot report a specific browser error code, so it raises a generic MediaPlaybackError. If an `onError` prop is supplied, the throw is skipped so the user can handle it.

Source

Thrown at packages/core/src/video/VideoForRendering.tsx:239

		current.addEventListener('ended', endedHandler, {once: true});

		const errorHandler = () => {
			if (current?.error) {
				// eslint-disable-next-line no-console
				console.error('Error occurred in video', current?.error);

				// If user is handling the error, we don't cause an unhandled exception
				if (onError) {
					return;
				}

				throw new MediaPlaybackError({
					message: `The browser threw an error while playing the video ${props.src}: Code ${current.error.code} - ${current?.error?.message}. See https://remotion.dev/docs/media-playback-error for help. Pass an onError() prop to handle the error.`,
					src: props.src as string,
				});
			} else {
				throw new MediaPlaybackError({
					message: 'The browser threw an error',
					src: props.src as string,
				});
			}
		};

		current.addEventListener('error', errorHandler, {once: true});

		// If video skips to another frame or unmounts, we clear the created handle
		return () => {
			seek.cancel();
			current.removeEventListener('ended', endedHandler);
			current.removeEventListener('error', errorHandler);
			continueRender(handle);
		};
	}, [
		volumePropsFrame,
		props.src,

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Pass an `onError` prop to the <Video> component so Remotion does not throw and you can log/recover instead.
  2. Verify the video `src` is reachable from the render environment (HTTP 200, correct CORS headers) before rendering.
  3. Host the asset on the same origin or a CDN with `Access-Control-Allow-Origin` set, and use a server-rendering-friendly format (MP4/H.264 with faststart).
  4. If the src is dynamic, ensure it resolves to a stable, fully loaded URL before the frame that plays it (preload with `staticFile()` or `usePreload`).

Example fix

// before
<Video src={maybeFlakyUrl} />

// after
<Video
  src={verifiedUrl}
  onError={(e) => {
    console.error('video error', e);
  }}
/>
Defensive patterns

Strategy: try-catch

Validate before calling

import {getRemotionEnvironment} from 'remotion';

// before rendering, confirm the URL is reachable
const ok = await fetch(src, {method: 'HEAD'}).then((r) => r.ok).catch(() => false);
if (!ok) throw new Error(`Video src not reachable: ${src}`);

Type guard

const isReachableUrl = (u: string): boolean => {
  try { return Boolean(new URL(u, window.location.origin)); } catch { return false; }
};

Try / catch

<Video
  src={src}
  onError={(e) => {
    // Remotion will NOT throw when onError is provided
    console.error('video playback error', e, currentError);
  }}
/>

Prevention

When it happens

Trigger: The 'error' event fires on the video element during rendering AND `current.error` is null/undefined at the moment the handler runs. This happens when the media resource fails to load for a reason the browser does not attach an error object to (e.g. network abort, context loss, the element being torn down mid-seek), and no `onError` prop was passed to the <Video>/<VideoForRendering> component.

Common situations: Rendering a composition whose video src 404s or is intermittently unreachable; the media URL changes while a render is in flight; CORS/security header rejection that surfaces as an error event without a populated HTMLMediaError; flaky CDN during Lambda rendering where the request is aborted before the browser populates `.error`.

Related errors


AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12). Data as JSON: /api/errors/0b3190c1c0a9c6a8. Report an issue: GitHub.