remotion-dev/remotion · error · Error

Failed to create WebGL vertex array

Error message

Failed to create WebGL vertex array

What it means

Thrown by setupColorKey when gl.createVertexArray() returns null after the program was built. A null VAO means the GL context cannot allocate a vertex-array object, pointing to resource exhaustion or context loss. The color key effect cannot bind vertex attributes without it, so setup fails.

Solutions

  1. Lower render concurrency to reduce the number of live VAOs/contexts.
  2. Render on a GPU-accelerated environment rather than software GL.
  3. Update GPU drivers and Chrome; retry if context loss was transient.
  4. Reduce the number of WebGL effects rendered in parallel.

Example fix

// before
remotion render main --concurrency=8

// after
remotion render main --concurrency=1
Defensive patterns

Strategy: retry

Validate before calling

function webgl2VaoAvailable(): boolean {
  try {
    const c = document.createElement('canvas');
    const gl = c.getContext('webgl2');
    if (!gl) return false;
    const v = gl.createVertexArray();
    const ok = v !== null;
    if (v) gl.deleteVertexArray(v);
    return ok;
  } catch {
    return false;
  }
}

Try / catch

try {
  await renderMedia({...});
} catch (err) {
  if (/Failed to create WebGL vertex array/i.test(String(err))) {
    await renderMedia({...opts, concurrency: 1});
  } else {
    throw err;
  }
}

Prevention

When it happens

Trigger: At color-key.ts:272 inside setupColorKey, before the VBO is created. gl.createVertexArray() yields null under GL object-limit/memory pressure or after context loss; independent of colorKey() parameters.

Common situations: Many concurrent WebGL2 contexts each holding VAOs, software GL (SwiftShader) with low VAO limits, GPU memory pressure, or a long render that lost its context.

Related errors


AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12). Data as JSON: /api/errors/722d333275fcf4b7. Report an issue: GitHub.

Appendix: source

Thrown at packages/effects/src/color-key.ts:272

};

const setupColorKey = (target: HTMLCanvasElement): ColorKeyState => {
	const gl = target.getContext('webgl2', {
		premultipliedAlpha: true,
		alpha: true,
		preserveDrawingBuffer: true,
	});
	if (!gl) {
		throw createWebGL2ContextError('color key effect');
	}

	gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);

	const program = createProgram(gl, COLOR_KEY_VS, COLOR_KEY_FS);

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

	gl.bindVertexArray(vao);

	const data = new Float32Array([
		-1, -1, 0, 0, 1, -1, 1, 0, -1, 1, 0, 1, 1, 1, 1, 1,
	]);

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

	gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
	gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW);

	const aPos = gl.getAttribLocation(program, 'aPos');
	const aUv = gl.getAttribLocation(program, 'aUv');

View on GitHub (pinned to 78fe4bb3fd)