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

  1. 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.
  2. 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.
  3. Check the environment: run natively instead of via RDP/X-forwarding/VM, or use a software/llvmpipe adapter when no display GPU is available.
  4. 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.
  5. 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

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


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)