unoplatform/uno · error · InvalidOperationException
Offscreen framebuffer is not complete
Error message
Offscreen framebuffer is not complete
What it means
GLCanvasElement's FrameBufferDetails allocates an offscreen GL framebuffer (color texture + depth/stencil renderbuffer) for offscreen rendering, then asserts gl.CheckFramebufferStatus == FramebufferComplete. If not, it throws InvalidOperationException. GL defines several incompleteness causes (missing attachment, mismatched dimensions, unsupported internal format, unsupported sample counts, no GL context current).
Source
Thrown at src/AddIns/Uno.WinUI.Graphics3DGL/GLCanvasElement.FrameBufferDetails.cs:51
gl.TexParameter(GLEnum.Texture2D, GLEnum.TextureMinFilter, (int)GLEnum.Linear);
gl.TexParameter(GLEnum.Texture2D, GLEnum.TextureMagFilter, (int)GLEnum.Linear);
gl.FramebufferTexture2D(GLEnum.Framebuffer, FramebufferAttachment.ColorAttachment0,
GLEnum.Texture2D, _textureColorBuffer, 0);
}
gl.BindTexture(GLEnum.Texture2D, 0);
_renderBuffer = gl.GenRenderbuffer();
gl.BindRenderbuffer(GLEnum.Renderbuffer, _renderBuffer);
{
gl.RenderbufferStorage(GLEnum.Renderbuffer, InternalFormat.Depth24Stencil8, (uint)renderSize.Width, (uint)renderSize.Height);
gl.FramebufferRenderbuffer(GLEnum.Framebuffer, GLEnum.DepthStencilAttachment,
GLEnum.Renderbuffer, _renderBuffer);
}
gl.BindRenderbuffer(GLEnum.Renderbuffer, 0);
if (gl.CheckFramebufferStatus(GLEnum.Framebuffer) != GLEnum.FramebufferComplete)
{
throw new InvalidOperationException("Offscreen framebuffer is not complete");
}
}
gl.BindFramebuffer(GLEnum.Framebuffer, 0);
}
public void Dispose()
{
_gl.DeleteFramebuffer(Framebuffer);
_gl.DeleteTexture(_textureColorBuffer);
_gl.DeleteRenderbuffer(_renderBuffer);
}
}
}
View on GitHub (pinned to 0418340488)
Solutions
- Guard against zero/negative RenderSize before creating the framebuffer; skip rendering until a valid size is set.
- Query gl.CheckFramebufferStatus's specific reason (gl.GetFramebufferAttachmentParameter / driver logs) to distinguish format vs. attachment failure.
- On drivers without Depth24Stencil8, fall back to a stencil-only or depth-only renderbuffer, or skip depth/stencil if your scene doesn't need it.
- Ensure a GL context is current on the calling thread when the framebuffer is built.
Example fix
// before
if (gl.CheckFramebufferStatus(GLEnum.Framebuffer) != GLEnum.FramebufferComplete)
{
throw new InvalidOperationException("Offscreen framebuffer is not complete");
}
// after
if (RenderSize.Width <= 0 || RenderSize.Height <= 0) { return; }
var status = gl.CheckFramebufferStatus(GLEnum.Framebuffer);
if (status != GLEnum.FramebufferComplete)
{
this.Log().Error($"Framebuffer incomplete: {status}");
return; // skip this frame rather than crash Defensive patterns
Strategy: validation
Validate before calling
if (RenderSize.Width <= 0 || RenderSize.Height <= 0) return; // skip degenerate size
Type guard
static bool ValidRenderSize(Size s) => s.Width > 0 && s.Height > 0;
Try / catch
try { BuildFramebuffer(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("framebuffer")) { this.Log().Error(ex); } Prevention
- Never allocate the framebuffer with a zero-sized render target.
- Verify GL context is current on the render thread before framebuffer ops.
- Confirm the driver supports GL_DEPTH24_STENCIL8 before requiring depth/stencil.
When it happens
Trigger: RenderSize has zero width or height; the depth/stencil InternalFormat (Depth24Stencil8) is unsupported by the GL driver; the framebuffer was bound without a current GL context; renderbuffer storage allocation silently failed on the driver.
Common situations: Element resized to 0x0 before first render; running on a GL driver lacking EXT_packed_depth_stencil / GL_DEPTH24_STENCIL8; context loss between framebuffer creation and the status check; running GLCanvasElement on a headless/Software GL context.
Related errors
- The framebuffer readback failed with {readbackError} while c
- GLCanvasElement.IsGLInitializedProperty is read-only.
- Program link failed: {infoLog}
- Program link failed: {infoLog}
- Readback FBO is not complete
AI-assisted analysis of unoplatform/uno@0418340488 (2026-08-13).
Data as JSON: /api/errors/092d28b5984f0774.
Report an issue: GitHub.