astrid-runtime/astrid · error

kernel returned an unexpected storage unmount response

Error message

kernel returned an unexpected storage unmount response

What it means

Thrown by `unmount_status` when the kernel's response to the unmount authorization check is neither `Success` nor a recognized `Error`. The provider cannot determine whether the lease is still valid, so it aborts the unmount rather than risking an inconsistent state.

Source

Thrown at crates/astrid-storage-provider-winfsp/src/main.rs:332

        AdminResponseBody::Error(error) => {
            bail!("kernel refused storage lifecycle request: {error}")
        },
        _ => bail!("kernel returned an unexpected storage lifecycle response"),
    }
}

fn unmount_status(body: AdminResponseBody) -> Result<bool> {
    match body {
        AdminResponseBody::Success(_) => Ok(true),
        AdminResponseBody::Error(error)
            if error.contains("was not found") || error.contains("expired or revoked") =>
        {
            Ok(false)
        },
        AdminResponseBody::Error(error) => {
            bail!("kernel refused storage unmount authorization: {error}")
        },
        _ => bail!("kernel returned an unexpected storage unmount response"),
    }
}

#[cfg(windows)]
fn prepare_mountpoint(
    requested: Option<PathBuf>,
    view: &astrid_core::storage_provider::StorageProviderViewV1,
) -> Result<(PathBuf, bool)> {
    let _ = view;
    let mountpoint = requested.map_or_else(first_free_drive, Ok)?;
    if !mountpoint.is_absolute() {
        bail!("mountpoint must be absolute");
    }
    if is_drive_target(&mountpoint) {
        if std::fs::metadata(&mountpoint).is_ok() {
            bail!(
                "Windows drive target is already in use: {}",
                mountpoint.display()

View on GitHub (pinned to affd8760f4)

Solutions

  1. Match provider and kernel versions so response variants are understood
  2. Check kernel logs for the actual response emitted to the unmount authorization request
  3. Extend `unmount_status` to handle the newly introduced response variant
Defensive patterns

Strategy: try-catch

Type guard

fn is_status_response(body: &AdminResponseBody) -> bool {
    matches!(body, AdminResponseBody::Success(_) | AdminResponseBody::Error(_))
}

Try / catch

match provider.unmount(lease).await {
    Err(e) if e.to_string().contains("unexpected storage unmount response") => {
        // protocol mismatch: do not force-unmount; escalate to version fix
    },
    other => handle(other),
}

Prevention

When it happens

Trigger: `unmount` performs the authorization check and the kernel returns an `AdminResponseBody` variant outside `Success`/`Error` — for instance a lease payload or an unrecognized enum variant from a newer kernel.

Common situations: Kernel and provider version mismatch after an admin API change; hitting the wrong admin endpoint that returns a lease or other typed payload instead of a status response.

Understand the failure class

Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.

Related errors


AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09). Data as JSON: /api/errors/2505815015a6e88b. Report an issue: GitHub.