remotion-dev/remotion · error · Error

is not available as a variable font

Error message

${meta.fontFamily} is not available as a variable font

What it means

loadVariableFonts() (exported from @remotion/google-fonts) loads variable font axes, but only works for fonts whose metadata marks them as variable (`meta.variable` present). For static-only families the variable info does not exist, so calling this function throws `${fontFamily} is not available as a variable font`.

Solutions

  1. Use `loadFont()` instead of `loadVariableFonts()` for families without a variable version — it loads static weights per style/weight
  2. Pick a family that actually ships a variable font on Google Fonts (check the family page for an "axes" panel)
  3. Verify the meta object belongs to the intended family (it comes from the same family's import, e.g. `import {getInfo} from "@remotion/google-fonts/Inter"`)
  4. If the family does have a variable font on Google Fonts, update @remotion/google-fonts to a version whose generated metadata includes it

Example fix

// before
import {loadVariableFonts, getInfo} from "@remotion/google-fonts/Roboto";
loadVariableFonts(getInfo(), "normal", {subsets: ["latin"]}); // static-only family
// after
import {loadFont} from "@remotion/google-fonts/Roboto";
const {fontFamily, waitUntilDone} = loadFont("normal", {weights: ["400", "700"]});
Defensive patterns

Strategy: try-catch

Validate before calling

import {getInfo} from "@remotion/google-fonts/Inter";
const meta = getInfo();
if (!meta.variable) {
  // fall back to loadFont() for static weights
}

Type guard

const supportsVariable = (
  meta: ReturnType<typeof getInfo>,
): meta is typeof meta & {variable: NonNullable<typeof meta.variable>} =>
  Boolean(meta.variable);

Try / catch

try {
  const vf = loadVariableFonts(meta, style, {subsets: ['latin'], ...options});
} catch (e) {
  if (e.message.includes('is not available as a variable font')) {
    // fall back to loadFont(meta.fontFamily === undefined ? style : style, ...)
    return loadFont(style as any, options);
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling loadVariableFonts(fontInfo, style, {subsets: [...]}) with a FontInfo meta object for a family that has no variable version — e.g. fonts like "Arial"-style static families, or families where the package only ships static weights. Also happens when passing meta from the wrong family (copy-paste between imports).

Common situations: Migrating code from loadFont() to loadVariableFonts() without checking that the chosen family offers a variable font on Google Fonts, using an older package version where the family had no variable metadata, or destructuring meta from one import and passing it to another family's loader.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of remotion-dev/remotion@46a3a6bf13 (2026-09-18). Data as JSON: /api/errors/6b5d9739cf9d1d36. Report an issue: GitHub.

Appendix: source

Thrown at packages/google-fonts/src/base.ts:259

	return {
		fontFamily: meta.fontFamily,
		fonts: meta.fonts,
		unicodeRanges: meta.unicodeRanges,
		waitUntilDone: () => Promise.all<void>(promises).then(() => undefined),
	};
};

export const loadVariableFonts = (
	meta: FontInfo,
	style: string,
	options: FontLoadOptions & {subsets: string[]},
): {
	fontFamily: FontInfo['fontFamily'];
	axes: Record<string, {min: number; max: number}>;
	waitUntilDone: () => Promise<undefined>;
} => {
	if (!meta.variable) {
		throw new Error(`${meta.fontFamily} is not available as a variable font`);
	}

	if (options.subsets.length === 0) {
		throw new Error('Pass at least one subset to loadVariableFont()');
	}

	const fontFacesForStyle = meta.variable.fontFaces.filter(
		(fontFace) => fontFace.style === style,
	);
	if (fontFacesForStyle.length === 0) {
		throw new Error(
			`The variable font ${meta.fontFamily} does not have a style ${style}`,
		);
	}

	const availableSubsetKeys = fontFacesForStyle.map(
		(fontFace) => fontFace.subset,
	);

View on GitHub (pinned to 46a3a6bf13)