emilk/egui · error
Failed to get display handle
Error message
Failed to get display handle
What it means
While building glutin `SurfaceAttributes`, eframe calls `window.window_handle()` (raw-window-handle's `HasWindowHandle`) and unwraps it with `.expect("Failed to get display handle")`. Note the message is misleading: it fetches the window handle (not the display handle), and panics if the platform backend cannot produce one for the newly created window.
Source
Thrown at crates/eframe/src/native/glow_integration.rs:1340
Some(window.scale_factor() as f32),
event_loop.system_theme(),
self.max_texture_side,
)
});
if viewport.gl_surface.is_none() {
log::debug!("Creating a gl_surface for viewport {viewport_id:?}");
// surface attributes
let (width_px, height_px): (u32, u32) = window.inner_size().into();
let width_px = NonZeroU32::new(width_px).unwrap_or(NonZeroU32::MIN);
let height_px = NonZeroU32::new(height_px).unwrap_or(NonZeroU32::MIN);
let surface_attributes = {
glutin::surface::SurfaceAttributesBuilder::<glutin::surface::WindowSurface>::new()
.build(
window
.window_handle()
.expect("Failed to get display handle")
.as_raw(),
width_px,
height_px,
)
};
log::trace!("creating surface with attributes: {surface_attributes:?}");
let gl_surface = unsafe {
self.gl_config
.display()
.create_window_surface(&self.gl_config, &surface_attributes)?
};
log::trace!("surface created successfully: {gl_surface:?}. making context current");
let not_current_gl_context =
if let Some(not_current_context) = self.not_current_gl_context.take() {
not_current_contextView on GitHub (pinned to 441971a776)
Solutions
- Ensure a functional display server is available (valid DISPLAY or WAYLAND_DISPLAY); in CI use Xvfb or run software rendering (LIBGL_ALWAYS_SOFTWARE=1).
- Align versions of eframe, egui-winit, glutin, and raw-window-handle (same trait major versions).
- Avoid closing/destroying viewports concurrently with surface creation; keep viewport teardown on the same event-loop thread.
- If maintaining a fork, use `window_handle().ok()` and return a graceful `Result` error instead of `.expect`.
Defensive patterns
Strategy: validation
Validate before calling
// preflight display-server check before starting the eframe app
fn can_create_surfaces() -> bool {
cfg!(target_os = "windows")
|| cfg!(target_os = "macos")
|| std::env::var_os("WAYLAND_DISPLAY").is_some()
|| std::env::var_os("DISPLAY").is_some()
} Try / catch
// internal .expect panic: cannot catch; validate environment first and fail fast
if !can_create_surfaces() {
eprintln!("No display server; cannot create GL surfaces");
std::process::exit(1);
} Prevention
- Verify DISPLAY/WAYLAND_DISPLAY or a native window system before launch.
- Use software rendering (LIBGL_ALWAYS_SOFTWARE=1) in containers/CI.
- Avoid tearing down viewports while their surfaces are being created; serialize on the event loop thread.
- Match raw-window-handle major versions across eframe/winit/glutin in Cargo.toml.
When it happens
Trigger: Surface creation for a viewport whose window cannot yield a raw window handle — window already destroyed, unsupported backend, or platform handle conversion failure on X11/Wayland/Win32.
Common situations: Wayland/X11 sessions in containers or nested compositors; drivers/backends reporting windows without exportable handles; eframe/egui-winit/raw-window-handle version mismatches; closing a viewport while its surface is being created.
Understand the failure class
Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.
Related errors
- Failed to get window handle
- failed to fit multisamples option of native_options into u8
- Single-use AppCreator has unexpectedly already been taken
- viewport doesn't exist
- Single-use AppCreator has unexpectedly already been taken
AI-assisted analysis of emilk/egui@441971a776 (2026-09-12).
Data as JSON: /api/errors/ed82790dac6dffb0.
Report an issue: GitHub.