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
- Render with a software WebGL backend: `npx remotion render <comp> --gl=swiftshader`.
- Reduce render concurrency so the per-frame WebGL context load stays within GPU limits.
- Restart the GPU process (relaunch Chrome / the render worker) to clear a lost-context state.
- 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
- Render with a software GL backend when GPU resources are constrained (`gl: 'swiftshader'`).
- Limit concurrency to keep the per-frame context load within GPU limits.
- Restart render workers periodically if you suspect context loss accumulation.
- Update GPU drivers / Chromium.
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
- Failed to create WebGL shader
- Failed to create WebGL texture
- Failed to create WebGL vertex array
- Failed to create WebGL buffer
- Failed to create WebGL shader
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/aa5cb52955187b6d.
Report an issue: GitHub.