remotion-dev/remotion · error

LUT_3D_SIZE exceeds this browser's maximum 3D texture size…

Error message

LUT_3D_SIZE ${parsed.size} exceeds this browser's maximum 3D texture size of ${maxSize}

What it means

applyLut() checks the parsed LUT's LUT_3D_SIZE against gl.getParameter(gl.MAX_3D_TEXTURE_SIZE), the largest 3D texture dimension the current browser/GPU supports. If the LUT grid is larger than that limit, the 3D texture upload would fail, so the library throws with both sizes in the message. The check runs only when the LUT content changes (cachedContent !== content).

Solutions

  1. Resample/downsample the LUT to a smaller LUT_3D_SIZE (e.g. 32 or 33) before passing it to the effect
  2. Query the limit first: gl.getParameter(gl.MAX_3D_TEXTURE_SIZE) and pick a LUT that fits
  3. Use a LUT exported at a standard small size such as 17 or 33
  4. Re-export the .cube from the grading tool with a reduced resolution

Example fix

// before: arbitrary large LUT
const lut = parseCubeLut(big128CubeFile);
// after: check hardware limit and downsample if needed
const maxSize = gl.getParameter(gl.MAX_3D_TEXTURE_SIZE);
if (lut.size > maxSize) {
  lut = downsampleCubeLut(lut, Math.min(32, maxSize));
}
Defensive patterns

Strategy: validation

Validate before calling

const maxSize = gl.getParameter(gl.MAX_3D_TEXTURE_SIZE);
const declaredSize = Number(cubeText.match(/LUT_3D_SIZE (\d+)/)?.[1]);
if (declaredSize > maxSize) {
  throw new Error(`LUT_3D_SIZE ${declaredSize} exceeds MAX_3D_TEXTURE_SIZE ${maxSize}`);
}

Try / catch

try {
  applyLut(state, content);
} catch (e) {
  if (e.message.startsWith('LUT_3D_SIZE')) {
    applyLut(state, downsampleCubeLut(parsed, 32));
  }
}

Prevention

When it happens

Trigger: Loading a .cube file with a large LUT_3D_SIZE (e.g. 128 or 256) on hardware whose MAX_3D_TEXTURE_SIZE is smaller (commonly 64 on some mobile GPUs); switching to a bigger LUT in a composition that already works with a smaller one.

Common situations: Mobile/older GPUs often cap 3D textures at 64; professional color-grading LUTs are frequently exported at size 33, 65 or higher and can exceed low-end limits; users download high-resolution creative LUTs without checking hardware support.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


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

Appendix: source

Thrown at packages/effects/src/lut/lut-runtime.ts:179

	height,
	content,
	parsed,
	flipSourceY,
}: {
	readonly state: LutState;
	readonly source: CanvasImageSource;
	readonly width: number;
	readonly height: number;
	readonly content: string;
	readonly parsed: ParsedCubeLut;
	readonly flipSourceY: boolean;
}): void => {
	const {gl, program, sourceTexture, lutTexture, uniforms, vao} = state;

	if (state.cachedContent !== content) {
		const maxSize = gl.getParameter(gl.MAX_3D_TEXTURE_SIZE) as number;
		if (parsed.size > maxSize) {
			throw new Error(
				`LUT_3D_SIZE ${parsed.size} exceeds this browser's maximum 3D texture size of ${maxSize}`,
			);
		}

		gl.activeTexture(gl.TEXTURE1);
		gl.bindTexture(gl.TEXTURE_3D, lutTexture);
		gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
		gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
		gl.texImage3D(
			gl.TEXTURE_3D,
			0,
			gl.RGBA16F,
			parsed.size,
			parsed.size,
			parsed.size,
			0,
			gl.RGBA,
			gl.FLOAT,

View on GitHub (pinned to 46a3a6bf13)