remotion-dev/remotion · critical · Error

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

Error message

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.

What it means

Thrown by the @remotion/gif <Gif> component (the GifForDevelopment variant used inside Remotion Studio) when the GIF at `src` cannot be fetched because the remote host blocked the request via CORS policy. The component first runs `isCorsError(error)` and, if true, re-throws with this CORS-specific guidance. It is a hard failure: the React render throws and the Studio preview breaks.

Source

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

					if (currentOnError.current) {
						currentOnError.current(err);
					} else {
						setError(err);
					}
				});

			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;
		}

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Move the GIF into your Remotion project's `public/` folder and reference it via `staticFile('anim.gif')` so it is served same-origin.
  2. Configure the hosting bucket/CDN to send `Access-Control-Allow-Origin: *` (or your specific Studio origin) for GIF responses.
  3. Open the browser Developer Tools Network tab, select the failing GIF request, and confirm the missing/incorrect CORS header before fixing the server.
  4. If you cannot control the remote host, download the GIF once and serve it locally instead of hotlinking.

Example fix

// before
<Gif src="https://third-party-cdn.com/anim.gif" />

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

Strategy: fallback

Validate before calling

import {staticFile} from 'remotion';

// Prefer same-origin assets to avoid CORS entirely.
const gifSrc = isRemoteUrl(src) && !hasCorsSupport(src)
  ? staticFile('anim.gif')
  : src;

Try / catch

// <Gif> throws during render; wrap an ErrorBoundary to keep Studio usable.
import {Component, type ReactNode} from 'react';

class GifBoundary extends Component<{children: ReactNode; fallback: ReactNode}, {hasError: boolean}> {
  state = {hasError: false};
  static getDerivedStateFromError() { return {hasError: true}; }
  render() { return this.state.hasError ? this.props.fallback : this.props.children; }
}

// <GifBoundary fallback={<Img src={placeholder} />}><Gif src={src} /></GifBoundary>

Prevention

When it happens

Trigger: Rendering `<Gif src="https://cdn.example.com/anim.gif" />` in the Remotion Studio preview where `cdn.example.com` does not return an `Access-Control-Allow-Origin` header that matches the Studio origin (e.g. localhost:3000). Also triggered when the host returns CORS headers for a different origin, or when credentials are sent but `Access-Control-Allow-Credentials` is missing.

Common situations: Pointing `src` at a production S3/Cloudflare bucket that has not been configured for cross-origin requests; hotlinking a GIF from a third-party site that actively blocks CORS; migrating assets but forgetting to enable CORS on the new bucket; using an http:// GIF from an https:// Studio (mixed content that surfaces as a fetch failure reported as CORS).

Related errors


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