remotion-dev/remotion · error · Error

Could not automatically derive font format from extension: $

Error message

Could not automatically derive font format from extension: ${ext}. Pass the "format" parameter explicitly.

What it means

The `getFontFormat` helper maps file extensions to CSS font formats: `.woff2` → `woff2`, `.woff` → `woff`, `.otf` → `opentype`, `.ttf` → `truetype`. If the URL's extension is none of these (e.g., `.eot`, `.svg`, or a URL with query parameters that obscure the extension), the function throws this error and asks you to pass `format` explicitly.

Source

Thrown at packages/fonts/src/get-font-format.ts:21

export const getFontFormat = (url: string): FontFormat => {
	if (typeof url !== 'string') {
		throw new TypeError(
			`Expected a URL string but received ${url === undefined ? 'undefined' : typeof url}. Make sure to pass a "url" field in the options object of loadFont().`,
		);
	}

	const ext = url.split('.').pop()?.toLowerCase();
	switch (ext) {
		case 'woff2':
			return 'woff2';
		case 'woff':
			return 'woff';
		case 'otf':
			return 'opentype';
		case 'ttf':
			return 'truetype';
		default:
			throw new Error(
				`Could not automatically derive font format from extension: ${ext}. Pass the "format" parameter explicitly.`,
			);
	}
};

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Pass the `format` option explicitly in `loadFont`: `format: 'woff2'`.
  2. Use a URL that ends in a recognized extension (`.woff2`, `.woff`, `.otf`, `.ttf`).
  3. For Google Fonts, use `@remotion/google-fonts` instead of manual `loadFont`.

Example fix

// before
loadFont({ family: 'MyFont', url: 'https://cdn.example.com/font?id=123' });

// after
loadFont({
  family: 'MyFont',
  url: 'https://cdn.example.com/font?id=123',
  format: 'woff2',
});
Defensive patterns

Strategy: validation

Validate before calling

const KNOWN_EXTS = ['woff2', 'woff', 'otf', 'ttf'];
const ext = url.split('.').pop()?.toLowerCase();
if (!ext || !KNOWN_EXTS.includes(ext)) {
  // pass format explicitly
  loadFont({ family, url, format: 'woff2' });
} else {
  loadFont({ family, url });
}

Try / catch

try {
  loadFont({ family, url });
} catch (err) {
  if (err instanceof Error && err.message.includes('derive font format')) {
    loadFont({ family, url, format: 'woff2' }); // retry with explicit format
  } else {
    throw err;
  }
}

Prevention

When it happens

Trigger: Passing a URL ending in `.eot`, `.svg`, or no extension; passing a URL with a query string like `font.woff2?v=2` is fine (extension is still `woff2`), but a URL like `https://cdn.example.com/font?id=123` (no extension) triggers it.

Common situations: Using a CDN or font-hosting service that serves fonts from dynamic URLs without file extensions, loading `.eot` fonts (legacy IE), or URLs where the extension is not the last path segment.

Related errors


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