remotion-dev/remotion · error

Failed to create LUT vertex buffer

Error message

Failed to create LUT vertex buffer

What it means

setupLut() calls gl.createBuffer() to allocate the VBO holding the fullscreen-quad vertex positions. A null return means the context could not allocate a buffer object, and this Error is thrown. This typically accompanies general WebGL context failure rather than a LUT-specific problem.

Solutions

  1. Reinitialize the effect after 'webglcontextrestored' fires
  2. Check gl.isContextLost() and recreate the context if true
  3. Audit for GL buffer leaks (buffers not deleted when effects unmount)
  4. Retry in a fresh browser context / after reducing GPU memory pressure

Example fix

// before: unbounded effect creation leaking buffers
effects.forEach((e) => setupLut(e));
// after: cleanup old state before re-creating
if (state) cleanupLut(state);
state = setupLut({ gl, width, height, lutContent });
Defensive patterns

Strategy: try-catch

Validate before calling

if (gl.isContextLost()) {
  throw new Error('WebGL context lost; cannot create LUT buffer');
}

Try / catch

try {
  state = setupLut({ gl, width, height, lutContent });
} catch (e) {
  if (e.message === 'Failed to create LUT vertex buffer') {
    // cleanup old GL state, recreate context or skip the effect
  }
}

Prevention

When it happens

Trigger: setupLut runs on a lost WebGL2 context; GPU memory/object limits are exhausted; a mocked GL object returns null from createBuffer.

Common situations: GPU resets during long renders; memory pressure on mobile; many concurrent effects leaking GL buffers; headless browsers without a functioning GL backend.

Related errors


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

Appendix: source

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

		premultipliedAlpha: true,
		alpha: true,
		preserveDrawingBuffer: true,
	});
	if (!gl) {
		throw createWebGL2ContextError('LUT effect');
	}

	gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);

	const program = createProgram(gl);
	const vao = gl.createVertexArray();
	if (!vao) {
		throw new Error('Failed to create LUT vertex array');
	}

	const vbo = gl.createBuffer();
	if (!vbo) {
		throw new Error('Failed to create LUT vertex buffer');
	}

	gl.bindVertexArray(vao);
	gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
	gl.bufferData(
		gl.ARRAY_BUFFER,
		new Float32Array([-1, -1, 0, 0, 1, -1, 1, 0, -1, 1, 0, 1, 1, 1, 1, 1]),
		gl.STATIC_DRAW,
	);
	gl.enableVertexAttribArray(0);
	gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 16, 0);
	gl.enableVertexAttribArray(1);
	gl.vertexAttribPointer(1, 2, gl.FLOAT, false, 16, 8);
	gl.bindVertexArray(null);

	return {
		gl,
		program,

View on GitHub (pinned to 46a3a6bf13)