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

  1. Reduce the number of concurrently-live WebGL2 effects/compositions and ensure each effect's cleanup callback runs between compositions so buffers are reclaimed.
  2. 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.
  3. Listen for the canvas 'webglcontextlost' event and treat it as transient: abort the frame and re-render after 'webglcontextrestored'.
  4. 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

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


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