remotion-dev/remotion · error · Error

Linear progressive blur framebuffer incomplete: 0x${status.t

Error message

Linear progressive blur framebuffer incomplete: 0x${status.toString(16)}

What it means

Thrown by setupLinearProgressiveBlur() when gl.checkFramebufferStatus() returns something other than FRAMEBUFFER_COMPLETE after attaching the intermediate RGBA texture. The hex status code is interpolated, so the specific GL incomplete reason (e.g. 0x8cd6 UNSUPPORTED, 0x8cd5 INCOMPLETE_ATTACHMENT) is visible.

Source

Thrown at packages/effects/src/linear-progressive-blur/linear-progressive-blur-runtime.ts:205

		0,
		gl.RGBA,
		gl.UNSIGNED_BYTE,
		null,
	);
	gl.bindTexture(gl.TEXTURE_2D, null);

	gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
	gl.framebufferTexture2D(
		gl.FRAMEBUFFER,
		gl.COLOR_ATTACHMENT0,
		gl.TEXTURE_2D,
		textureIntermediate,
		0,
	);
	const status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
	gl.bindFramebuffer(gl.FRAMEBUFFER, null);
	if (status !== gl.FRAMEBUFFER_COMPLETE) {
		throw new Error(
			`Linear progressive blur framebuffer incomplete: 0x${status.toString(16)}`,
		);
	}

	return {
		gl,
		programHorizontal,
		programVertical,
		vao,
		vbo,
		textureSource,
		textureIntermediate,
		framebuffer,
		horizontal: getUniforms(gl, programHorizontal),
		vertical: getUniforms(gl, programVertical),
	};
};

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Decode the interpolated status hex: 0x8cd6=FRAMEBUFFER_UNSUPPORTED, 0x8cd5=INCOMPLETE_ATTACHMENT, 0x8cd7=MISSING_ATTACHMENT, 0x8219=INCOMPLETE_DIMENSIONS.
  2. Confirm the target canvas has non-zero width/height before the effect mounts (Remotion compositions must render at >=1x1).
  3. Switch GL backend to a complete implementation: `--gl=angle --angle-backend=swiftshader`.
  4. Restart Chrome / the worker to rule out a crashed GPU process and retry.
  5. Update GPU drivers/mesa; if persistent on one driver, report to @remotion/effects with the status code and driver string.

Example fix

// before — composition can render at 0x0 during init, tripping INCOMPLETE_DIMENSIONS
//   const comp = <Composition id="C" component={...} width={0} height={0} fps={30} durationInFrames={90} />;

// after
//   const comp = <Composition id="C" component={...} width={1920} height={1080} fps={30} durationInFrames={90} />;
Defensive patterns

Strategy: validation

Validate before calling

// Validate dimensions + color-renderability before mounting the effect.
function isValidBlurTarget(canvas: HTMLCanvasElement): boolean {
  if (canvas.width < 1 || canvas.height < 1) return false; // INCOMPLETE_DIMENSIONS guard
  const gl = canvas.getContext('webgl2');
  if (!gl) return false;
  const tex = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, tex);
  gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
  const fbo = gl.createFramebuffer(); gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
  gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
  const complete = gl.checkFramebufferStatus(gl.FRAMEBUFFER) === gl.FRAMEBUFFER_COMPLETE;
  gl.bindFramebuffer(gl.FRAMEBUFFER, null);
  gl.deleteFramebuffer(fbo); gl.deleteTexture(tex);
  return complete;
}

Try / catch

try {
  renderWithLinearProgressiveBlur();
} catch (err) {
  if (err instanceof Error && err.message.startsWith('Linear progressive blur framebuffer incomplete')) {
    // err.message contains the hex status — decode it, then switch GL backend or fix dimensions.
    console.error(err.message);
    await withGlBackend('swiftshader', () => renderWithLinearProgressiveBlur());
  } else throw err;
}

Prevention

When it happens

Trigger: The intermediate RGBA texture is incompatible with framebuffer rendering on this driver — typically because the chosen internal format (gl.RGBA) is not color-renderable on the implementation, the texture's dimensions are zero, or mip-level settings are inconsistent. Also seen when the texture storage was never allocated correctly (e.g. texImage2D failed silently).

Common situations: Drivers/GPUs where RGBA8 is not color-renderable in WebGL2 (rare but possible on stripped software rasterizers); a target canvas with zero width or height feeding `Math.max(1, target.width)`; outdated mesa/SwiftShader; a GPU-process crash leaving framebuffer state inconsistent.

Related errors


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