remotion-dev/remotion · error

Unsupported LUT header

Error message

Unsupported LUT header "${keyword}" on line ${index + 1}.

What it means

parseCubeLut only understands a fixed set of .cube header keywords: TITLE, LUT_1D_SIZE, LUT_3D_SIZE, DOMAIN_MIN, DOMAIN_MAX, LUT_1D_INPUT_RANGE, LUT_3D_INPUT_RANGE. Any other ALL-CAPS keyword line that looks like a header (matches /^[A-Z][A-Z0-9_]*$/) is rejected with the line number, since silently ignoring unknown headers could change how the LUT is applied. The thrown message names the unsupported keyword and its 1-based line.

Solutions

  1. Open the .cube file at the reported line and delete or comment out the unsupported header.
  2. Rename a misspelled supported header to the correct keyword (e.g. LUT_1D_SIZES -> LUT_1D_SIZE).
  3. Convert the LUT to a plain spec-compliant .cube using a tool like imageio/lut utilities.
  4. Extend the parser if the header is meaningful and you control the code.
  5. Strip unknown headers programmatically before parsing (lines matching /^[A-Z][A-Z0-9_]*$/ not in the known set).

Example fix

// before
LUT_3D_NAME "cinematic"
LUT_3D_SIZE 33
// after
TITLE "cinematic"
LUT_3D_SIZE 33
Defensive patterns

Strategy: validation

Validate before calling

const KNOWN = new Set(['TITLE','LUT_1D_SIZE','LUT_3D_SIZE','DOMAIN_MIN','DOMAIN_MAX','LUT_1D_INPUT_RANGE','LUT_3D_INPUT_RANGE']);
const bad = text.split(/\r?\n/).findIndex((l) => {
  const kw = l.trim().split(/\s+/)[0];
  return /^[A-Z][A-Z0-9_]*$/.test(kw) && !KNOWN.has(kw);
});
if (bad !== -1) throw new Error(`Unsupported header on line ${bad + 1}`);

Try / catch

let lut;
try {
  lut = parseCubeLut(text);
} catch (e) {
  console.error(`LUT header problem: ${(e as Error).message}`);
  lut = null;
}

Prevention

When it happens

Trigger: parseCubeLut encounters an uppercase header keyword outside the supported set before any color data has been consumed, e.g. 'LUT_3D_NAME "my lut"', 'VERSION 2', 'ORIGIN_COMMERCIAL ...' or vendor-specific headers emitted by some grading tools.

Common situations: .cube files from DaVinci Resolve, Lattice or other tools that append non-standard metadata headers; newer .cube spec extensions; copy-pasted headers with typos like 'LUT_1D_SIZES'.

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/66fb9a4f9b1cf0c4. Report an issue: GitHub.

Appendix: source

Thrown at packages/studio/src/helpers/cube-lut.ts:100

			continue;
		}

		if (keyword === 'LUT_1D_INPUT_RANGE' || keyword === 'LUT_3D_INPUT_RANGE') {
			if (
				numbers.length !== 2 ||
				!numbers.every(Number.isFinite) ||
				numbers[0] >= numbers[1]
			) {
				throw new Error(`${keyword} must contain an increasing input range.`);
			}

			domainMin = [numbers[0], numbers[0], numbers[0]];
			domainMax = [numbers[1], numbers[1], numbers[1]];
			continue;
		}

		if (isHeader) {
			throw new Error(
				`Unsupported LUT header "${keyword}" on line ${index + 1}.`,
			);
		}

		if (data === null) {
			throw new Error('Expected LUT_1D_SIZE or LUT_3D_SIZE before color data.');
		}

		const color = [Number(keyword), ...numbers];
		if (
			color.length !== 3 ||
			!color.every((value) => Number.isFinite(Math.fround(value)))
		) {
			throw new Error(`Invalid LUT color on line ${index + 1}.`);
		}

		if (offset + 3 > data.length) {
			throw new Error(`Expected ${data.length / 3} LUT colors, got more.`);

View on GitHub (pinned to 46a3a6bf13)