remotion-dev/remotion · critical · Error
Blur framebuffer incomplete: 0x${status.toString(16)}
Error message
Blur framebuffer incomplete: 0x${status.toString(16)} What it means
Thrown by `setupBlur` after the intermediate framebuffer is assembled and `gl.checkFramebufferStatus(gl.FRAMEBUFFER)` returns a value other than FRAMEBUFFER_COMPLETE. The hex status code is embedded (e.g. 0x8cd6 = FRAMEBUFFER_INCOMPLETE_ATTACHMENT). This is a format/config incompatibility between the intermediate texture and the framebuffer attachment, not a resource exhaustion error.
Source
Thrown at packages/effects/src/blur/blur-runtime.ts:187
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(`Blur framebuffer incomplete: 0x${status.toString(16)}`);
}
return {
gl,
programHorizontal,
programVertical,
vao,
vbo,
textureSource,
textureIntermediate,
framebuffer,
horizontal: getBlurUniforms(gl, programHorizontal),
vertical: getBlurUniforms(gl, programVertical),
};
};
export const cleanupBlur = (state: BlurState): void => {
const {View on GitHub (pinned to 78fe4bb3fd)
Solutions
- Decode the hex status in the message (0x8cd6 incomplete attachment, 0x8cdb unsupported, 0x8cd9 dimensions mismatch) to find the cause.
- Ensure the target canvas has non-zero width/height before `setupBlur`.
- Update GPU drivers; FBO completeness bugs are driver-specific.
- Report the status code and GL_RENDERER upstream if it persists on compliant hardware.
- Reduce frame resolution to rule out max-texture-size limits.
Example fix
// before: setup on an unsized canvas const state = setupBlur(canvas); // canvas.width === 0 // after: ensure a real size first canvas.width = Math.max(1, canvas.width); canvas.height = Math.max(1, canvas.height); const state = setupBlur(canvas);
Defensive patterns
Strategy: validation
Validate before calling
// Ensure the canvas has real dimensions before setup. const w = Math.max(1, target.width | 0); const h = Math.max(1, target.height | 0); target.width = w; target.height = h; // Optionally probe FBO completeness on a throwaway texture before committing.
Try / catch
try {
const state = setupBlur(canvas);
} catch (err) {
if (/framebuffer incomplete/i.test(err.message)) {
// decode status hex, adjust canvas size / resolution, retry
} else { throw err; }
} Prevention
- Never call setupBlur on a zero-width/zero-height canvas.
- Keep frame dimensions within the GPU's max texture size.
- Log the hex status code and GL_RENDERER to triage driver-specific FBO issues.
When it happens
Trigger: Fires at line 186-187 when `status !== gl.FRAMEBUFFER_COMPLETE`. The FBO attaches an RGBA/UNSIGNED_BYTE texture sized to `target.width`/`target.height` (clamped to >=1).
Common situations: Zero-sized canvas (`width`/`height` were 0 and clamped to 1, but the attachment still fails on some drivers); driver does not support the chosen internalformat/format combo for render-to-texture; context in a degraded state; the canvas was resized to 0 before setup.
Related errors
- Failed to create WebGL framebuffer
- Shader compile failed: ${log ?? '(no log)'}
- Program link failed: ${log ?? '(no log)'}
- Program link failed: ${log ?? '(no log)'}
- Failed to create WebGL shader
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/68ed021ad5817044.
Report an issue: GitHub.