GraphiteEditor/Graphite · critical
Failed to create surface
Error message
Failed to create surface
What it means
Panic when wgpu's instance.create_surface fails while creating the presentation surface from the winit window. create_surface returns a CreateSurfaceError when the platform cannot bind the window's raw handle to a GPU surface: missing/unsupported windowing backend (Wayland vs X11 mismatches), missing EGL/Vulkan client libraries, unsupported window types, or a stale/invalid window handle.
Source
Thrown at desktop/src/window.rs:92
Self {
winit_window: winit_window.into(),
native_handle,
custom_cursors: HashMap::new(),
clipboard,
}
}
pub(crate) fn show(&self) {
self.winit_window.set_visible(true);
self.winit_window.focus_window();
}
pub(crate) fn request_redraw(&self) {
self.winit_window.request_redraw();
}
pub(crate) fn create_surface(&self, instance: &WgpuInstance) -> WgpuSurface {
instance.create_surface(self.winit_window.clone()).expect("Failed to create surface")
}
pub(crate) fn pre_present_notify(&self) {
self.winit_window.pre_present_notify();
}
pub(crate) fn can_render(&self) -> bool {
self.native_handle.can_render()
}
pub(crate) fn surface_size(&self) -> winit::dpi::PhysicalSize<u32> {
self.winit_window.surface_size()
}
pub(crate) fn scale_factor(&self) -> f64 {
self.winit_window.scale_factor()
}
View on GitHub (pinned to c507b35645)
Solutions
- Install the platform GL client libraries (libegl1, libgl1, libvulkan1, and X11/Wayland variants) and retry
- Force the other windowing backend (run under XWayland or a native Wayland session) to rule out backend mismatch
- Print/inspect the CreateSurfaceError variant to identify which backend is failing
- In headless environments, run the editor with a virtual display that exposes at least software GL (e.g., Xvfb + swrast) or use the web build
Example fix
// before
instance.create_surface(self.winit_window.clone()).expect("Failed to create surface")
// after
instance.create_surface(self.winit_window.clone()).unwrap_or_else(|e| panic!("Failed to create surface: {e}")) Defensive patterns
Strategy: try-catch
Try / catch
match instance.create_surface(self.winit_window.clone()) {
Ok(surface) => surface,
Err(e) => {
eprintln!("Failed to create surface: {e}");
eprintln!("Install EGL/Vulkan client libraries or try the other windowing backend (Wayland vs X11).");
std::process::exit(1);
}
} Prevention
- Install the platform GL client libraries (libEGL, libvulkan, X11/Wayland GL packages) on minimal systems
- Test both Wayland and X11 sessions when surface creation fails on Linux
- Log the CreateSurfaceError variant; it names the failing backend and reason
When it happens
Trigger: Running on Linux without the required EGL/Vulkan libraries (libEGL, libvulkan loader, X11 GLX libs) present; running under Xvfb or a VNC session with no accelerated visuals; a Wayland/X11 mismatch between winit and the installed graphics stack; creating the surface after the window handle has become invalid.
Common situations: Minimal Linux/container environments lacking the client GL libraries; remote desktop sessions without GPU support; systems where only software rendering is available but the surface backend can't attach to it; version mismatches between wgpu and winit raw-window-handle versions.
Related errors
- Failed to create WGPU context
- Failed to create WgpuExecutor
- GPU executor should be available when we receive a texture
- Failed to create surface from canvas
- Buffer mapping communication failed
AI-assisted analysis of GraphiteEditor/Graphite@c507b35645 (2026-08-16).
Data as JSON: /api/errors/0b8bd135ea9e6eaf.
Report an issue: GitHub.