gfx-rs/wgpu · error

Unexpected Vulkan error: {_err:?}

Error message

Unexpected Vulkan error: {_err:?}

What it means

wgpu-hal's Vulkan backend converts unrecognized vk::Result values into `DeviceError::Unexpected`. If the crate is built with the `internal_error_panic` feature flag, this helper instead panics so unexpected Vulkan results fail loudly during development. Normally the caller receives an Unexpected error rather than a panic.

Source

Thrown at wgpu-hal/src/vulkan/mod.rs:1839

/// Maps
///
/// - VK_ERROR_OUT_OF_HOST_MEMORY
/// - VK_ERROR_OUT_OF_DEVICE_MEMORY
/// - VK_PIPELINE_COMPILE_REQUIRED_EXT
/// - VK_ERROR_INVALID_SHADER_NV
fn map_pipeline_err(err: vk::Result) -> crate::DeviceError {
    // We don't use VK_EXT_pipeline_creation_cache_control
    // VK_PIPELINE_COMPILE_REQUIRED_EXT
    // We don't use VK_NV_glsl_shader
    // VK_ERROR_INVALID_SHADER_NV
    map_host_device_oom_err(err)
}

/// Returns [`crate::DeviceError::Unexpected`] or panics if the `internal_error_panic`
/// feature flag is enabled.
fn get_unexpected_err(_err: vk::Result) -> crate::DeviceError {
    #[cfg(feature = "internal_error_panic")]
    panic!("Unexpected Vulkan error: {_err:?}");

    #[allow(unreachable_code)]
    crate::DeviceError::Unexpected
}

/// Returns [`crate::DeviceError::OutOfMemory`].
fn get_oom_err(_err: vk::Result) -> crate::DeviceError {
    crate::DeviceError::OutOfMemory
}

/// Returns [`crate::DeviceError::Lost`] or panics if the `device_lost_panic`
/// feature flag is enabled.
fn get_lost_err() -> crate::DeviceError {
    #[cfg(feature = "device_lost_panic")]
    panic!("Device lost");

    #[allow(unreachable_code)]
    crate::DeviceError::Lost

View on GitHub (pinned to 3e11ff59bf)

Solutions

  1. If the panic fired, treat it as a bug: capture the printed VkResult variant and driver/GPU info.
  2. Update GPU drivers; many unexpected results stem from driver quirks.
  3. Rebuild without the `internal_error_panic` feature to receive a graceful DeviceError::Unexpected instead of panicking.
  4. Check for an earlier device-loss event; subsequent calls may return unexpected results after the device died.

Example fix

// before (Cargo.toml)
wgpu-hal = { version = "...", features = ["internal_error_panic"] }
// after
wgpu-hal = { version = "..." }
Defensive patterns

Strategy: try-catch

Type guard

// Narrow DeviceError before deciding recovery
fn is_recoverable(err: &wgpu::DeviceError) -> bool {
    matches!(err, wgpu::DeviceError::Lost | wgpu::DeviceError::OutOfMemory)
}
// DeviceError::Unexpected means an unmapped VkResult: log and treat as fatal.

Try / catch

match queue.submit(Some(encoder.finish())) {
    Ok(()) => {}
    Err(e) if matches!(*e, wgpu::DeviceError::Lost | wgpu::DeviceError::OutOfMemory) => recreate_device(),
    Err(e) => log::error!("unexpected Vulkan error: {e}"), // DeviceError::Unexpected
}

Prevention

When it happens

Trigger: Any Vulkan call in the backend returning an error result that is not explicitly mapped (e.g. not OUT_OF_MEMORY or DEVICE_LOST), routed through `get_unexpected_err` at wgpu-hal/src/vulkan/mod.rs:1839.

Common situations: Driver bugs returning exotic VkResult codes; device-loss variants (DEVICE_LOST_EXTENSION etc.); builds with internal_error_panic enabled running the CTS; hardware removal mid-frame.

Related errors


AI-assisted analysis of gfx-rs/wgpu@3e11ff59bf (2026-09-03). Data as JSON: /api/errors/119d21342acbb11c. Report an issue: GitHub.