remotion-dev/remotion · error · Error

Failed to create WebGL texture

Error message

Failed to create WebGL texture

What it means

Thrown by createPixelateState when gl.createTexture() returns null after VAO, VBO, and attribute wiring all succeeded. Textures are the largest GL resource pixelate allocates, so this is the most likely allocation to fail under memory pressure. The guard prevents bindTexture/texParameteri from operating on null.

Source

Thrown at packages/effects/src/pixelate.ts:160

	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');
	}

	gl.bindTexture(gl.TEXTURE_2D, texture);
	gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
	gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
	gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
	gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
	gl.bindTexture(gl.TEXTURE_2D, null);

	return {
		gl,
		program,
		vao,
		vbo,
		texture,
		uSource: gl.getUniformLocation(program, 'uSource'),
		uResolution: gl.getUniformLocation(program, 'uResolution'),
		uBlockSize: gl.getUniformLocation(program, 'uBlockSize'),

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Compare source dimensions to `gl.getParameter(gl.MAX_TEXTURE_SIZE)` and downscale if exceeded.
  2. Lower composition resolution.
  3. Reduce concurrent texture-backed effects.
  4. Increase Lambda function memory.
  5. Confirm `gl.isContextLost()` is false and remount if true.

Example fix

// before
import {pixelate} from '@remotion/effects';
const effect = pixelate();

// after — verify texture capacity for the source size
function textureFits(gl: WebGL2RenderingContext, w: number, h: number): boolean {
  const max = gl.getParameter(gl.MAX_TEXTURE_SIZE) as number;
  return w <= max && h <= max && !gl.isContextLost();
}
Defensive patterns

Strategy: try-catch

Validate before calling

function textureCapacityOk(gl: WebGL2RenderingContext, w: number, h: number): boolean {
  if (gl.isContextLost()) return false;
  const max = gl.getParameter(gl.MAX_TEXTURE_SIZE) as number;
  if (w > max || h > max) return false;
  const t = gl.createTexture();
  if (t) gl.deleteTexture(t);
  return t !== null;
}

Try / catch

try {
  pixelate();
} catch (err) {
  if (/Failed to create WebGL texture/.test((err as Error).message)) {
    // downscale source / reduce resolution, then retry
  }
  throw err;
}

Prevention

When it happens

Trigger: pixelate setup reaches the final block; gl.createTexture() returns null.

Common situations: Large source frames being uploaded each tick; many texture-backed effects in one composition; mobile/integrated GPUs with limited VRAM; SwiftShader on a low-memory Lambda function; source exceeding MAX_TEXTURE_SIZE.

Related errors


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