emilk/egui · critical
The surface isn't supported by this adapter
Error message
The surface isn't supported by this adapter
What it means
During surface configuration, egui-wgpu calls surface.get_default_config(adapter, width, height) and expects Some; the expect panics with "The surface isn't supported by this adapter" when wgpu cannot produce a default configuration. This means the adapter cannot render to the given surface at all — typically the surface's target display/plane is not usable by the selected adapter — so no valid SurfaceConfiguration (usage/format present mode etc.) exists and rendering to this window is impossible with this adapter.
Solutions
- Create the wgpu adapter and the surface compatibly: obtain the adapter via instance.request_adapter with compatible_surface: Some(&surface) so the chosen adapter supports the window.
- On hybrid GPUs, iterate request_adapter options and pick an adapter whose get_default_config for the surface is Some, falling back to another backend (e.g. GL) otherwise.
- Check the environment: run natively instead of via RDP/X-forwarding/VM, or use a software/llvmpipe adapter when no display GPU is available.
- Before configuring, guard the call: match on get_default_config yourself and show a graceful error instead of panicking inside the egui-wgpu render loop.
- Ensure the window is valid and shown before creating/configuring the surface.
Example fix
// before: adapter chosen without surface compatibility
let adapter = instance.request_adapter(&RequestAdapterOptions { power_preference: HighPerformance, ..Default::default() }).await.unwrap();
// ... later: egui_wgpu panics: surface isn't supported by this adapter
// after: request an adapter compatible with the surface
let adapter = instance
.request_adapter(&wgpu::RequestAdapterOptions {
power_preference: wgpu::PowerPreference::HighPerformance,
compatible_surface: Some(&surface),
force_fallback_adapter: false,
})
.await
.expect("no adapter that supports this surface"); Defensive patterns
Strategy: validation
Validate before calling
// Rust: verify surface/adapter compatibility before letting egui-wgpu configure
if surface.get_default_config(&adapter, width, height).is_none() {
eprintln!("surface not supported by this adapter; requesting a compatible adapter");
// re-request adapter with compatible_surface: Some(&surface)
} Type guard
fn supports_surface(instance: &wgpu::Instance, adapter: &wgpu::Adapter, surface: &wgpu::Surface<'_>, w: u32, h: u32) -> bool {
surface.get_default_config(adapter, w, h).is_some()
} Try / catch
// wgpu surfaces return errors as device callbacks; install a scope that captures them
let err_scope = wgpu::util::initialize_adapter_from_env_or_default(...) /* and */
// capture panics/lost-config errors at app level:
std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| renderer.draw(...)))
.or_else(|_| show_fallback_message("GPU cannot present to this window")) Prevention
- Always request the adapter with compatible_surface: Some(&surface).
- Test on hybrid-GPU laptops, VMs and remote-desktop environments before shipping.
- Guard get_default_config yourself and degrade gracefully instead of panicking in the render loop.
When it happens
Trigger: Configuring a surface on an adapter that doesn't support it: e.g. a window on a different GPU than the one wgpu picked, headless/offscreen environments where the surface has no display, virtual machines / remote desktops without present support, or adapters from a backend (e.g. GL) that can't drive the window system surface. Also surfaces created for a window that was closed or not yet visible on some platforms.
Common situations: Hybrid laptops (NVIDIA Optimus) where the app runs on the discrete GPU while the window belongs to the iGPU display; running in WSL, SSH X-forwarding, VMs or Wayland-less containers; multi-monitor setups where the window is moved to a monitor the adapter can't present to; picking a specific adapter (power_preference/pick_adapter) that doesn't own the display.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Failed to create image
- Failed to create render state
- Failed to create staging buffer for index data. Index count
- Failed to create staging buffer for vertex data. Vertex…
- install_surface called before render_state initialization
AI-assisted analysis of emilk/egui@8fb03c9ae9 (2026-09-12).
Data as JSON: /api/errors/257e733795d087e6.
Report an issue: GitHub.
Appendix: source
Thrown at crates/egui-wgpu/src/winit.rs:120
let desired_maximum_frame_latency = if surface_state.resizing {
Some(desired_maximum_frame_latency.unwrap_or(2).max(2))
} else {
desired_maximum_frame_latency
};
let width = surface_state.width;
let height = surface_state.height;
let mut surf_config = wgpu::SurfaceConfiguration {
usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
format: render_state.target_format,
present_mode,
alpha_mode: surface_state.alpha_mode,
view_formats: vec![render_state.target_format],
..surface_state
.surface
.get_default_config(&render_state.adapter, width, height)
.expect("The surface isn't supported by this adapter")
};
if let Some(desired_maximum_frame_latency) = desired_maximum_frame_latency {
surf_config.desired_maximum_frame_latency = desired_maximum_frame_latency;
}
surface_state
.surface
.configure(&render_state.device, &surf_config);
}
/// Drop the existing [`wgpu::Surface`] for `viewport_id` and create a fresh one for the
/// given window via [`wgpu::Instance::create_surface`], then configure it.
///
/// Used to recover from [`wgpu::CurrentSurfaceTexture::Lost`], where reconfiguring the
/// existing surface object cannot recover.
fn recreate_surface(
&mut self,View on GitHub (pinned to 8fb03c9ae9)