remotion-dev/remotion · error · Error
Failed to create WebGL buffer
Error message
Failed to create WebGL buffer
What it means
Thrown by pixelDissolve's createFullscreenQuad when gl.createBuffer() returns null after the VAO was already allocated and bound. WebGL2 returns null on buffer allocation when the context is lost or GPU memory for vertex buffers is exhausted. The null-check aborts before bindBuffer/bufferData would silently no-op.
Source
Thrown at packages/effects/src/pixel-dissolve.ts:254
return program;
};
const createFullscreenQuad = (
gl: WebGL2RenderingContext,
): {
readonly vao: WebGLVertexArrayObject;
readonly vbo: WebGLBuffer;
} => {
const vao = gl.createVertexArray();
if (!vao) {
throw new Error('Failed to create WebGL vertex array');
}
gl.bindVertexArray(vao);
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,
new Float32Array([-1, -1, 0, 0, 1, -1, 1, 0, -1, 1, 0, 1, 1, 1, 1, 1]),
gl.STATIC_DRAW,
);
return {vao, vbo};
};
export const pixelDissolve = createEffect<
PixelDissolveParams,
PixelDissolveState
>({
type: 'dev.remotion.effects.pixelDissolve',
label: 'pixelDissolve()',View on GitHub (pinned to 78fe4bb3fd)
Solutions
- Free other GPU resources before mounting pixelDissolve — unload unused video/image sources and other WebGL effects first.
- Check that the context is not lost: `const ext = gl.getExtension('WEBGL_lose_context'); gl.isContextLost()` and remount if true.
- On Lambda, use a larger memory function (3008 MB+) so Chrome has more headroom for GPU buffers.
- Reduce concurrent pixelDissolve instances to one per composition pass.
- If reproducible only on a specific machine, update or roll back the GPU driver.
Example fix
// before
import {pixelDissolve} from '@remotion/effects';
const effect = pixelDissolve();
// after — verify the live context can allocate before relying on the effect
function glCanAllocateBuffer(gl: WebGL2RenderingContext): boolean {
if (gl.isContextLost()) return false;
const probe = gl.createBuffer();
const ok = probe !== null;
if (probe) gl.deleteBuffer(probe);
return ok;
} Defensive patterns
Strategy: try-catch
Validate before calling
function glCanCreateBuffer(gl: WebGL2RenderingContext): boolean {
if (gl.isContextLost()) return false;
const b = gl.createBuffer();
if (b) gl.deleteBuffer(b);
return b !== null;
} Try / catch
try {
pixelDissolve();
} catch (err) {
if (/Failed to create WebGL buffer/.test((err as Error).message)) {
// free other GPU resources and retry, or fall back to a non-WebGL effect
}
throw err;
} Prevention
- Free unused video/image sources before mounting many effects.
- Keep concurrent WebGL2 effect count low in one composition.
- Monitor gl.isContextLost() before each render pass.
- Use a Lambda function with enough memory for buffer headroom.
When it happens
Trigger: pixelDissolve setup reaches createBuffer() (VAO succeeded) but the GL implementation refuses to allocate a new ARRAY_BUFFER. This is the second allocation in createFullscreenQuad, so it implies the context was healthy enough to make a VAO but degraded by the time a buffer was requested.
Common situations: GPU memory pressure from many simultaneously loaded video textures; context loss arriving between the VAO and buffer calls; SwiftShader under memory pressure in Lambda; a buggy driver that caps buffer count below the VAO count.
Related errors
- Failed to create WebGL vertex array
- Failed to create WebGL texture
- Failed to create WebGL shader
- Failed to create WebGL program
- Failed to create white balance texture
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/9ccf253078d88dc5.
Report an issue: GitHub.