remotion-dev/remotion · critical · Error
Failed to create WebGL buffer
Error message
Failed to create WebGL buffer
What it means
Thrown inside setupNoiseDisplacement (packages/effects/src/noise-displacement.ts:478) when gl.createBuffer() returns null while allocating the fullscreen-quad vertex buffer for the noiseDisplacement effect. A null return is the WebGL spec's signal that the WebGL2 context is lost, out of GPU memory, or has too many live buffer objects, so the buffer could not be created. Because setup runs on the first apply of the effect, this aborts the current Remotion render frame with no in-band fallback.
Source
Thrown at packages/effects/src/noise-displacement.ts:478
const fs = compileShader(gl, gl.FRAGMENT_SHADER, NOISE_DISPLACEMENT_FS);
const program = linkProgram(gl, vs, fs);
gl.deleteShader(vs);
gl.deleteShader(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');
gl.enableVertexAttribArray(aPos);
gl.vertexAttribPointer(aPos, 2, gl.FLOAT, false, 16, 0);
gl.enableVertexAttribArray(aUv);
gl.vertexAttribPointer(aUv, 2, gl.FLOAT, false, 16, 8);
gl.bindVertexArray(null);
const texture = gl.createTexture();
if (!texture) {
throw new Error('Failed to create WebGL texture');
}View on GitHub (pinned to 78fe4bb3fd)
Solutions
- Reduce the number of concurrently-live WebGL2 effects/compositions and ensure each effect's cleanup callback runs between compositions so buffers are reclaimed.
- Render on a host with a working GPU, or launch headless Chrome with WebGL enabled (e.g. --use-gl=angle / --enable-webgl) so the context is not starved or lost.
- Listen for the canvas 'webglcontextlost' event and treat it as transient: abort the frame and re-render after 'webglcontextrestored'.
- If the environment cannot supply a stable WebGL2 context, render the composition without the noiseDisplacement effect as a fallback.
Example fix
// before: effect setup throws and aborts the whole render
import {noiseDisplacement} from '@remotion/effects';
// after: probe WebGL2 health before relying on the effect, fall back otherwise
const probe = document.createElement('canvas');
const gl = probe.getContext('webgl2');
const canUse = !!gl && !!gl.createBuffer(); // null => context cannot allocate
const effects = canUse ? [noiseDisplacement({center: [0.5, 0.5], radius: 0.4})] : []; Defensive patterns
Strategy: try-catch
Validate before calling
// Probe that WebGL2 can allocate a buffer before relying on noiseDisplacement
function canAllocateNoiseDisplacementBuffer(): boolean {
try {
const c = document.createElement('canvas');
const gl = c.getContext('webgl2');
if (!gl || gl.isContextLost()) return false;
const buf = gl.createBuffer();
const ok = !!buf;
if (buf) gl.deleteBuffer(buf);
return ok;
} catch {
return false;
}
} Try / catch
try {
scene.push(noiseDisplacement({center: [0.5, 0.5], radius: 0.4}));
} catch (err) {
if (/Failed to create WebGL buffer/.test(String(err?.message))) {
// skip the effect; render without it
} else {
throw err;
}
} Prevention
- Run effect cleanup between compositions so GL buffers are reclaimed.
- Cap the number of simultaneous WebGL2 effects in one render.
- Render with GPU-enabled headless Chrome and handle webglcontextlost events.
- Probe allocation health on the render host before committing a GPU-heavy render.
When it happens
Trigger: Applying noiseDisplacement({...}) and rendering/previewing at the instant the canvas WebGL2 context is lost (GPU reset, WEBGL_lose_context), or when GPU memory is exhausted; running enough concurrent WebGL2 effects that the per-context live-buffer budget is hit.
Common situations: Headless Chrome rendering on a GPU-less CI host under SwiftShader memory pressure; a long Studio session leaking GL contexts; Chrome's GPU process crashing mid-render; Windows ANGLE/D3D hitting resource limits with many parallel compositions.
Related errors
- Failed to create WebGL texture
- Failed to create WebGL shader
- Failed to create WebGL program
- Failed to create WebGL shader
- Failed to create WebGL program
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/742de7895bce4bb8.
Report an issue: GitHub.