unoplatform/uno · critical · InvalidOperationException
wglCreateContext failed
Error message
wglCreateContext failed
What it means
After the pixel format is set, wglCreateContext(_hdc) creates the GL rendering context; it returns NULL on failure and the wrapper throws InvalidOperationException. wglCreateContext fails when the HDC has no valid pixel format set, the driver cannot allocate a context (out of GPU memory), the GDI/DLL opengl32 is unavailable, or the application is in a session type (e.g. certain service/RDP contexts) that disallows GL context creation.
Source
Thrown at src/AddIns/Uno.WinUI.Graphics3DGL/Windows/WinUINativeOpenGLWrapper.cs:75
// To inspect the chosen pixel format:
// WindowsRenderingNativeMethods.PIXELFORMATDESCRIPTOR temp_pfd = default;
// WindowsRenderingNativeMethods.DescribePixelFormat(_hdc, _pixelFormat, (uint)Marshal.SizeOf<WindowsRenderingNativeMethods.PIXELFORMATDESCRIPTOR>(), ref temp_pfd);
if (pixelFormat == 0)
{
throw new InvalidOperationException("ChoosePixelFormat failed");
}
if (WindowsRenderingNativeMethods.SetPixelFormat(_hdc, pixelFormat, ref pfd) == 0)
{
throw new InvalidOperationException("SetPixelFormat failed");
}
_glContext = WindowsRenderingNativeMethods.wglCreateContext(_hdc);
if (_glContext == IntPtr.Zero)
{
throw new InvalidOperationException("wglCreateContext failed");
}
}
// https://sharovarskyi.com/blog/posts/csharp-win32-opengl-silknet/
public bool TryGetProcAddress(string proc, out nint addr)
{
if (_opengl32.Value != IntPtr.Zero && NativeLibrary.TryGetExport(_opengl32.Value, proc, out addr))
{
return true;
}
addr = WindowsRenderingNativeMethods.wglGetProcAddress(proc);
return addr != IntPtr.Zero;
}
public nint GetProcAddress(string proc)
{
if (TryGetProcAddress(proc, out var address))View on GitHub (pinned to 0418340488)
Solutions
- Guarantee ChoosePixelFormat + SetPixelFormat succeeded on the same HDC before wglCreateContext (chain the checks).
- Reduce the number of simultaneously live GL contexts to free GPU handles.
- Install/repair GPU drivers and opengl32.dll; verify the session is an interactive desktop.
- Call Marshal.GetLastWin32Error / GetLastError for the specific failure reason and surface it.
Defensive patterns
Strategy: validation
Validate before calling
if (_glContext == IntPtr.Zero)
{
int err = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
throw new InvalidOperationException($"wglCreateContext failed (Win32 {err})");
} Prevention
- Chain the checks: pixel format first, then wglCreateContext on the same DC.
- Limit the number of simultaneously live GL contexts.
- Run GL hosts on an interactive desktop with working GPU drivers.
When it happens
Trigger: HDC's pixel format not actually set (so [53] should have thrown earlier but didn't, e.g. custom code path); GPU memory exhausted; opengl32.dll missing/unloaded; session has no interactive desktop.
Common situations: Too many live GL contexts exhausting GPU handles; corrupt/missing GPU driver; running the GL host in a non-interactive session; running on a server with no GPU and a software GL stack that rejects context creation.
Related errors
- No function was found with the name {proc}.
- ChoosePixelFormat failed
- SetPixelFormat failed
- PInvoke.RegisterClassEx failed: {Win32Helper.GetErrorMessage
- PInvoke.CreateWindowEx failed: {Win32Helper.GetErrorMessage(
AI-assisted analysis of unoplatform/uno@0418340488 (2026-08-13).
Data as JSON: /api/errors/0dd7b66e0d6ccef0.
Report an issue: GitHub.