remotion-dev/remotion · error · Error

Failed to create WebGL program

Error message

Failed to create WebGL program

What it means

Thrown by duotone's linkProgram() when gl.createProgram() returns null after both shaders compiled. The two shader objects were created fine, but the driver refused to allocate a program object, signalling context loss or resource exhaustion.

Source

Thrown at packages/effects/src/duotone.ts:159

	gl.shaderSource(shader, source);
	gl.compileShader(shader);
	if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
		const log = gl.getShaderInfoLog(shader);
		gl.deleteShader(shader);
		throw new Error(`Duotone shader compile failed: ${log ?? '(no log)'}`);
	}

	return shader;
};

const linkProgram = (
	gl: WebGL2RenderingContext,
	vs: WebGLShader,
	fs: WebGLShader,
): WebGLProgram => {
	const program = gl.createProgram();
	if (!program) {
		throw new Error('Failed to create WebGL program');
	}

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

	return program;
};

const createProgram = (
	gl: WebGL2RenderingContext,
	vertexSource: string,
	fragmentSource: string,

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Render with a software WebGL backend: `npx remotion render <comp> --gl=swiftshader`.
  2. Reduce render concurrency so the per-frame WebGL context load stays within GPU limits.
  3. Restart the GPU process (relaunch Chrome / the render worker) to clear a lost-context state.
  4. Update the GPU driver / Chromium build.
Defensive patterns

Strategy: try-catch

Try / catch

async function safeRender(opts) {
  try {
    return await renderMedia(opts);
  } catch (err) {
    if (/Failed to create WebGL program/.test(String(err?.message ?? ''))) {
      return await renderMedia({...opts, gl: 'swiftshader'});
    }
    throw err;
  }
}

Prevention

When it happens

Trigger: Happens during setupDuotone() on a frame where the WebGL2 context has been lost or GPU program-object memory is exhausted between compileShader() and linkProgram().

Common situations: GPU process crash or driver reset mid-setup, running many concurrent GPU-effect renders, or a constrained/containerized GPU with limited program slots.

Related errors


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