gfx-rs/wgpu · error

wgpu-hal ran into a preventable internal error: {txt}

Error message

wgpu-hal ran into a preventable internal error: {txt}

What it means

This panic is wgpu-hal's generic internal error hook for failures that are not invariant violations (usage errors) but still indicate a preventable problem inside a HAL backend implementation. It is raised via `hal_internal_error`, a cold `panic!` helper in wgpu-hal/src/lib.rs, meaning a backend hit an unexpected condition that upstream validation should normally have prevented. Because it is a panic (not a Result), it aborts the calling thread and indicates a wgpu bug or mis-wired backend rather than ordinary user error.

Source

Thrown at wgpu-hal/src/lib.rs:517

        gpu_allocator::AllocationSizes::new(
            value.min_device_memblock_size,
            value.min_host_memblock_size,
        )
        .with_max_device_memblock_size(value.max_device_memblock_size)
        .with_max_host_memblock_size(value.max_host_memblock_size)
    }
}

#[allow(dead_code, reason = "may be unused on some platforms")]
#[cold]
fn hal_usage_error<T: fmt::Display>(txt: T) -> ! {
    panic!("wgpu-hal invariant was violated (usage error): {txt}")
}

#[allow(dead_code, reason = "may be unused on some platforms")]
#[cold]
fn hal_internal_error<T: fmt::Display>(txt: T) -> ! {
    panic!("wgpu-hal ran into a preventable internal error: {txt}")
}

#[derive(Clone, Debug, Eq, PartialEq, Error)]
pub enum ShaderError {
    #[error("Compilation failed: {0:?}")]
    Compilation(String),
    #[error(transparent)]
    Device(#[from] DeviceError),
}

#[derive(Clone, Debug, Eq, PartialEq, Error)]
pub enum PipelineError {
    #[error("Linkage failed for stage {0:?}: {1}")]
    Linkage(wgt::ShaderStages, String),
    #[error("Entry point for stage {0:?} is invalid")]
    EntryPoint(naga::ShaderStage),
    #[error(transparent)]
    Device(#[from] DeviceError),

View on GitHub (pinned to 3e11ff59bf)

Solutions

  1. Reproduce with WGPU_BACKTRACE=1 to get a stack trace and file a wgpu issue with the message and backend/driver info
  2. Check that required wgpu::Features are requested on the device before using the feature that panicked
  3. Update wgpu to the latest version in case the backend bug is already fixed
  4. If using wgpu-hal directly, add the missing validation/check that the invariant expects

Example fix

// before
let device = adapter.request_device(&desc, None)?; // desc.features = Features::empty()
shader uses feature X -> hal_internal_error
// after
let mut features = wgt::Features::empty();
features.insert(wgt::Features::EXPERIMENTAL_X);
let device = adapter.request_device(&DeviceDescriptor { features, ..Default::default() }, None)?;
Defensive patterns

Strategy: validation

Validate before calling

if !device.features().contains(required_feature) {
    panic/return Err("feature X not enabled for this device");
}

Try / catch

std::panic::catch_unwind(|| device.create_render_pipeline(&desc))

Prevention

When it happens

Trigger: Any wgpu-hal backend code path that calls `hal_internal_error(...)` when a backend-specific condition cannot be fulfilled at runtime (e.g. a device/adapter capability or surface configuration that the backend assumed valid but turns out not to be). It is the companion of `hal_usage_error` (invariant violations) and is never intentionally triggered by user API calls.

Common situations: Hitting a backend bug while using bleeding-edge or experimental features (ray tracing, etc.), running on a driver with unusual behavior, or using wgpu internals directly (e.g. writing a custom backend or bypassing wgpu-core validation). Also seen when a feature gate is missing so a capability check fails deep in the HAL.

Related errors


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