remotion-dev/remotion · critical · Error

Failed to create WebGL program

Error message

Failed to create WebGL program

What it means

Thrown by setupFlannel when gl.createProgram() returns null after the shaders compiled. WebGL2 returns null only on context loss or severe resource exhaustion, so this is a GPU-level allocation failure rather than a link error (link errors surface as 607).

Source

Thrown at packages/effects/src/flannel.ts:223

	return shader;
};

const setupFlannel = (target: HTMLCanvasElement): FlannelState => {
	const gl = target.getContext('webgl2', {
		premultipliedAlpha: true,
		alpha: true,
		preserveDrawingBuffer: true,
	});
	if (!gl) {
		throw createWebGL2ContextError('flannel effect');
	}

	gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
	const vertexShader = compileShader(gl, gl.VERTEX_SHADER, FLANNEL_VS);
	const fragmentShader = compileShader(gl, gl.FRAGMENT_SHADER, FLANNEL_FS);
	const program = gl.createProgram();
	if (!program) {
		throw new Error('Failed to create WebGL program');
	}

	gl.attachShader(program, vertexShader);
	gl.attachShader(program, fragmentShader);
	gl.linkProgram(program);
	gl.deleteShader(vertexShader);
	gl.deleteShader(fragmentShader);
	if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
		const log = gl.getProgramInfoLog(program);
		gl.deleteProgram(program);
		throw new Error(`Flannel program link failed: ${log ?? '(no log)'}`);
	}

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

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Lower the concurrent WebGL effect count.
  2. Retry the render job on a fresh Chrome process.
  3. Use a machine/AMI with a healthier GPU or more VRAM.
Defensive patterns

Strategy: retry

Try / catch

let effect;
for (let attempt = 0; attempt < 3; attempt++) {
  try {
    effect = flannel(params);
    break;
  } catch (err) {
    if (attempt === 2 || !/WebGL|program/i.test(String(err))) throw err;
    await new Promise((r) => setTimeout(r, 200 * (attempt + 1)));
  }
}

Prevention

When it happens

Trigger: Lost WebGL context between shader compile and program creation; GPU memory exhausted by other effects/contexts; driver bug refusing to allocate the program object.

Common situations: Stacking many WebGL effects across sequences; rendering on resource-constrained headless Chrome; resumed render after GPU reset.

Related errors


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