astrid-runtime/astrid · error

kernel returned an unexpected storage lifecycle response

Error message

kernel returned an unexpected storage lifecycle response

What it means

into_success() pattern-matches the AdminResponseBody and only accepts Success or Error variants; any other variant (e.g. a lease payload returned where a plain ack was expected) triggers this bail. It indicates a protocol/shape mismatch between the provider and the kernel rather than a refused operation.

Source

Thrown at crates/astrid-storage-provider-fskit/src/main.rs:303

    }
    Ok(())
}

fn lease_from_response(body: AdminResponseBody) -> Result<StorageMountLeaseV1> {
    match body {
        AdminResponseBody::StorageMountLease(lease) => Ok(*lease),
        AdminResponseBody::Error(error) => bail!("kernel refused storage mount: {error}"),
        _ => bail!("kernel returned an unexpected storage mount response"),
    }
}

fn into_success(body: AdminResponseBody) -> Result<serde_json::Value> {
    match body {
        AdminResponseBody::Success(value) => Ok(value),
        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"),
    }
}

View on GitHub (pinned to affd8760f4)

Solutions

  1. Rebuild both the kernel and the fskit provider from the same commit so the AdminResponseBody enum matches.
  2. Check which AdminRequestKind was sent and whether its documented response variant changed; update into_success() to handle the new variant.
  3. Log the raw response body to identify which variant was actually received.

Example fix

// before
_ => bail!("kernel returned an unexpected storage lifecycle response"),
// after: accept a lease payload where the kernel now returns one
AdminResponseBody::StorageMountLease(_) => Ok(serde_json::Value::Null),
_ => bail!("kernel returned an unexpected storage lifecycle response"),
Defensive patterns

Strategy: type-guard

Validate before calling

// verify build compatibility before shipping: same AdminResponseBody schema in kernel and provider

Type guard

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

Try / catch

match into_success(body) {
    Ok(v) => Ok(v),
    Err(e) if e.to_string().contains("unexpected storage lifecycle response") => {
        Err(e.context("kernel/provider protocol mismatch"))
    },
    Err(e) => Err(e),
}

Prevention

When it happens

Trigger: A lifecycle request in execute() or unmount() returns a non-Success, non-Error AdminResponseBody variant — typically after a kernel version change that altered the AdminResponseBody enum, or a corrupted/misdeserialized reply.

Common situations: Kernel and fskit provider built from mismatched versions; a request that unexpectedly returns a StorageMountLease where Success was expected; middleware or proxy rewriting kernel responses.

Related errors


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