remotion-dev/remotion · error · Error

Failed to render GIF with source ${src}: "${error.message}".

Error message

Failed to render GIF with source ${src}: "${error.message}".

What it means

Thrown by the @remotion/gif <Gif> component (GifForDevelopment, used in Remotion Studio) when fetching or decoding the GIF failed for any reason OTHER than CORS. The component logs `error.stack` to the console and re-throws the original message wrapped with the `src`. It indicates the URL was reachable-or-unreachable but the response could not be turned into a usable GIF.

Source

Thrown at packages/gif/src/GifForDevelopment.tsx:115

				});

			return () => {
				if (!done) {
					aborted = true;
					cancel();
				}
			};
		}, [cacheKey, resolvedSrc]);

		if (error) {
			console.error(error.stack);
			if (isCorsError(error)) {
				throw new Error(
					`Failed to render GIF with source ${src}: "${error.message}". You must enable CORS for this URL. Open the Developer Tools to see exactly why this fetch failed.`,
				);
			}

			throw new Error(
				`Failed to render GIF with source ${src}: "${error.message}".`,
			);
		}

		const index = useCurrentGifIndex({
			delays: state.delays,
			loopBehavior,
			playbackRate,
		});

		if (index === -1) {
			return null;
		}

		return (
			<Canvas
				fit={fit}
				index={index}

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Open `src` directly in a browser to confirm it loads and is a valid GIF.
  2. Check the console (the full `error.stack` is logged just before the throw) for the underlying cause such as a 404 or parse error.
  3. Verify the URL is correct and the host returns HTTP 200 with image/gif content.
  4. If the file is local, confirm it lives under `public/` and is referenced via `staticFile()`.

Example fix

// before
<Gif src="https://example.com/missing-file.gif" />

// after
<Gif src={staticFile('confirmed-existing.gif')} />
Defensive patterns

Strategy: validation

Validate before calling

// Validate the URL returns a 2xx image/gif before mounting the component.
async function gifIsReachable(url: string): Promise<boolean> {
  try {
    const res = await fetch(url, {method: 'HEAD'});
    return res.ok && /image\/(gif|webp)/.test(res.headers.get('content-type') ?? '');
  } catch {
    return false;
  }
}

Try / catch

import {Component, type ReactNode} from 'react';

class GifBoundary extends Component<{children: ReactNode; fallback: ReactNode}, {hasError: boolean}> {
  state = {hasError: false};
  static getDerivedStateFromError() { return {hasError: true}; }
  componentDidCatch(err: Error) { console.error('Gif failed:', err.message); }
  render() { return this.state.hasError ? this.props.fallback : this.props.children; }
}

// <GifBoundary fallback={<div>Asset unavailable</div>}><Gif src={src} /></GifBoundary>

Prevention

When it happens

Trigger: `<Gif src="..." />` where the URL returns HTTP 404/403/500, the response body is not valid GIF data (corrupt or a different format served with the wrong extension), the network is down, or the GIF parser rejects the bytes.

Common situations: Typo in the `src` URL pointing to a non-existent file; the remote server is temporarily down; a build process copied a non-GIF file with a .gif extension; the asset moved or was deleted between environments; an aborted fetch because the component unmounted mid-load.

Related errors


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