dotnet/maui · critical · SystemException
Unable to create a device context from the specified device
Error message
Unable to create a device context from the specified device information.
What it means
NativeMethods.CreateDeviceContext (CreateIC path) throws SystemException("Unable to create a device context from the specified device information.") when the resulting SafeDC handle is invalid after CreateDC/CreateIC. The shell's standard interop wrapper treats an invalid GDI device-context handle as fatal because subsequent rendering/metrics calls would all fail.
Source
Thrown at src/Compatibility/Core/src/WPF/Microsoft.Windows.Shell/Standard/NativeMethods.cs:1488
{
SafeDC dc = null;
try
{
// Should this really be on the driver parameter?
dc = NativeMethods.CreateDC(deviceName, null, IntPtr.Zero, IntPtr.Zero);
}
finally
{
if (dc != null)
{
dc._created = true;
}
}
if (dc.IsInvalid)
{
dc.Dispose();
throw new SystemException("Unable to create a device context from the specified device information.");
}
return dc;
}
[SuppressMessage("Microsoft.Usage", "CA2201:DoNotRaiseReservedExceptionTypes"), SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
public static SafeDC CreateCompatibleDC(SafeDC hdc)
{
SafeDC dc = null;
try
{
IntPtr hPtr = IntPtr.Zero;
if (hdc != null)
{
hPtr = hdc.handle;
}
dc = NativeMethods.CreateCompatibleDC(hPtr);
if (dc == null)View on GitHub (pinned to f377ff1c5e)
Solutions
- Run the code on an interactive desktop session (or mock the device-context dependency in CI).
- Validate the device name (lpszDevice) before calling CreateIC; fall back to DISPLAY or null.
- Monitor GDI handle count and release SafeDC handles promptly to avoid exhaustion.
- For services, run the rendering in a session-0 interactive process or use a virtual display.
Example fix
// before
using (var dc = NativeMethods.CreateIC("BadDevice", null, null, null)) { ... }
// after
var device = IsValidDeviceName("BadDevice") ? "BadDevice" : null;
using (var dc = NativeMethods.CreateIC(device, null, null, null)) { ... } Defensive patterns
Strategy: validation
Validate before calling
if (string.IsNullOrEmpty(device) || !IsKnownDevice(device)) device = null; using var dc = NativeMethods.CreateIC(device, null, null, null);
Type guard
static bool HasInteractiveDesktop =>
System.Windows.Application.Current != null &&
!System.Windows.Application.Current.Dispatcher.HasShutdownStarted; Try / catch
try { using var dc = NativeMethods.CreateIC(device, null, null, null); }
catch (SystemException ex) when (ex.Message.Contains("device context"))
{ /* fall back to GetDC(IntPtr.Zero) or report headless env */ } Prevention
- Run on an interactive desktop session; mock GDI in CI.
- Validate device names before CreateIC; fall back to DISPLAY.
- Dispose SafeDC promptly to avoid handle exhaustion.
When it happens
Trigger: Calling CreateDC/CreateIC with a device name or DEVMODE that the system rejects; running under a session with no display (services, RDP disconnect, headless CI); GDI handle exhaustion; corrupted display driver state.
Common situations: Headless CI/service context where no interactive desktop exists; invalid printer/display device name; GDI resource leak exhausting the session handle pool; remote session teardown mid-call.
Related errors
- Unable to initialize GDI+
- Unable to combine two HRGNs.
- Unable to find the required services. Please add all the req
- RootComponent requires a value for its Selector property, bu
- RootComponent requires a value for its ComponentType propert
AI-assisted analysis of dotnet/maui@f377ff1c5e (2026-08-13).
Data as JSON: /api/errors/f37e0ced0da72462.
Report an issue: GitHub.