remotion-dev/remotion · error · Error

Failed to create white balance texture

Error message

Failed to create white balance texture

What it means

The white balance effect allocates a GPU texture (gl.createTexture) during its one-time WebGL2 setup to hold the source frame it color-corrects. WebGL returns null when the context is lost, the GPU is out of resources, or too many textures/contexts are alive, and the effect treats null as fatal because it cannot sample video frames without it. This is an environment/resource failure, not a parameter mistake: the shader and texture parameters are fixed by the library.

Source

Thrown at packages/effects/src/white-balance.ts:170

	gl.attachShader(program, vertexShader);
	gl.attachShader(program, fragmentShader);
	gl.linkProgram(program);
	gl.deleteShader(vertexShader);
	gl.deleteShader(fragmentShader);

	if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
		const log = gl.getProgramInfoLog(program);
		gl.deleteProgram(program);
		throw new Error(`White balance shader link failed: ${log ?? '(no log)'}`);
	}

	return program;
};

const createTexture = (gl: WebGL2RenderingContext): WebGLTexture => {
	const texture = gl.createTexture();
	if (!texture) {
		throw new Error('Failed to create white balance texture');
	}

	gl.bindTexture(gl.TEXTURE_2D, texture);
	gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
	gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
	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.bindTexture(gl.TEXTURE_2D, null);
	return texture;
};

const setupWhiteBalance = (target: HTMLCanvasElement): WhiteBalanceState => {
	const gl = target.getContext('webgl2', {
		premultipliedAlpha: true,
		alpha: true,
		preserveDrawingBuffer: true,
	});
	if (!gl) {

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Verify WebGL2 is actually available and healthy: in the render browser, check that canvas.getContext('webgl2') returns a non-null context and that gl.isContextLost() is false before relying on the effect.
  2. For headless rendering (Lambda/CI), ensure Chromium launches with GPU/WebGL enabled (e.g. flags enabling SwiftShader) and is not on the GPU blocklist; Remotion's bundled Chrome already does this, so avoid overriding --disable-gpu or --disable-software-rasterizer.
  3. Reduce the number of effects/compositions holding live WebGL contexts concurrently, or render in passes, to stay under the browser's context limit (~16).
  4. Listen for the webglcontextlost event on the render canvas and re-mount the composition to re-create the context and state.
  5. Update GPU drivers / switch from a headless software backend to a real GPU when rendering locally.

Example fix

// before: assumes WebGL2 can always allocate
import {whiteBalance} from '@remotion/effects';

// after: feature-detect before mounting effects that need WebGL2
const probe = document.createElement('canvas').getContext('webgl2');
const supportsEffect = probe != null && !probe.isContextLost();

<VideoEffects effects={supportsEffect ? [whiteBalance({temperature: 0.3})] : []} />
Defensive patterns

Strategy: try-catch

Validate before calling

// Probe WebGL2 health before mounting whiteBalance
const gl = document.createElement('canvas').getContext('webgl2');
const webglOk = gl != null && !gl.isContextLost();
if (!webglOk) {
  // skip the effect, log, or fall back to a non-WebGL color adjustment
}

Type guard

const hasHealthyWebGL2 = (): boolean => {
  const gl = document.createElement('canvas').getContext('webgl2');
  return gl != null && !gl.isContextLost();
};

Try / catch

import {whiteBalance} from '@remotion/effects';

try {
  return <VideoEffects effects={[whiteBalance({temperature: 0.3})]} />;
} catch (err) {
  if (err instanceof Error && err.message.includes('white balance texture')) {
    // GPU unavailable: render without the effect
    return <Video />;
  }
  throw err;
}

Prevention

When it happens

Trigger: First render frame that applies the whiteBalance() effect on a machine whose WebGL2 context cannot allocate a texture: a lost context (webglcontextlost already fired), GPU memory exhausted, or a headless browser with WebGL disabled. The throw happens inside setupWhiteBalance -> createTexture, before any frame is drawn.

Common situations: Headless Chromium in CI/AWS Lambda with software rendering (SwiftShader) misconfigured or GPU blocklisted; too many @remotion/effects compositions mounted at once on one page each grabbing a context; a GPU driver crash or tab suspension that triggered context loss; running in a Remote Desktop / VM without GPU acceleration.

Related errors


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