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
- Open the .cube file at the reported line and delete or comment out the unsupported header.
- Rename a misspelled supported header to the correct keyword (e.g. LUT_1D_SIZES -> LUT_1D_SIZE).
- Convert the LUT to a plain spec-compliant .cube using a tool like imageio/lut utilities.
- Extend the parser if the header is meaningful and you control the code.
- 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
- Strip vendor-specific metadata headers before parsing
- Only ship spec-compliant .cube files
- Keep a sanitizer that comments out unknown ALL-CAPS header lines
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
- Combined 1D and 3D LUTs are not supported.
- Duplicate on line .
- Expected LUT colors, got more.
- Expected LUT colors, got .
- Expected LUT_1D_SIZE or LUT_3D_SIZE.
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)