astrid-runtime/astrid · error

kernel returned an unexpected storage lifecycle response

Error message

kernel returned an unexpected storage lifecycle response

What it means

kernel_lease_status matches the admin response against AdminResponseBody::Success and AdminResponseBody::Error; any other AdminResponseBody variant (catch-all _) is a response shape the provider doesn't understand, so it bails. This guards against kernel/provider protocol drift where new response variants exist but the FUSE provider binary predates them.

Source

Thrown at crates/astrid-storage-provider-fuse/src/main.rs:767

        .request(AdminRequestKind::StorageMountStatus {
            mount_id: *mount_id,
        })
        .await?;
    match body {
        AdminResponseBody::Success(value) => {
            let status =
                serde_json::from_value(value).context("decode kernel storage mount status")?;
            Ok(Some(status))
        },
        AdminResponseBody::Error(error)
            if error.contains("was not found") || error.contains("expired or revoked") =>
        {
            Ok(None)
        },
        AdminResponseBody::Error(error) => {
            bail!("kernel refused storage lifecycle request: {error}")
        },
        _ => bail!("kernel returned an unexpected storage lifecycle response"),
    }
}

async fn require_live_lease(
    client: &mut AdminClient,
    acting_principal: &astrid_core::PrincipalId,
    record: &registry::MountRecord,
) -> Result<LeaseStatus> {
    if &record.requested_by != acting_principal {
        bail!("mount was issued to another acting principal");
    }
    kernel_lease_status(client, &record.mount_id)
        .await?
        .with_context(|| format!("storage mount lease {} is stale", record.mount_id))
}

fn validate_record(record: &registry::MountRecord, status: &LeaseStatus) -> Result<()> {
    if status.mountpoint != record.mountpoint || status.access != record.access {

View on GitHub (pinned to affd8760f4)

Solutions

  1. Rebuild/redeploy the FUSE provider and kernel from the same source revision so AdminResponseBody variants match
  2. Log the raw response body to identify which unexpected variant the kernel returned
  3. Pin kernel and provider versions in deployment so they upgrade together
  4. Add an explicit match arm for the new variant in kernel_lease_status if it represents a legitimate state

Example fix

// before
_ => bail!("kernel returned an unexpected storage lifecycle response"),
// after: handle the new variant explicitly
AdminResponseBody::Pending { retry_after } => { /* handle */ }
_ => bail!("kernel returned an unexpected storage lifecycle response"),
Defensive patterns

Strategy: type-guard

Validate before calling

// Detect version drift before calling lifecycle APIs
let caps = client.request(AdminRequestKind::Handshake).await?;
if caps.protocol_version != PROVIDER_PROTOCOL_VERSION {
    return Err(anyhow!("kernel/provider protocol mismatch: {} vs {}", caps.protocol_version, PROVIDER_PROTOCOL_VERSION));
}

Type guard

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

Try / catch

match kernel_lease_status(client, &mount_id).await {
    Err(e) if e.to_string().contains("unexpected storage lifecycle response") => {
        log_raw_response_for_diagnostics();
        // redeploy provider and kernel from the same revision, then retry
    }
    other => other,
}

Prevention

When it happens

Trigger: The kernel admin endpoint returns a new/unknown AdminResponseBody variant for StorageMountStatus — typically a version mismatch between kernel and provider binaries, or a proxy rewriting the response.

Common situations: Rolling upgrade where the kernel is newer than the FUSE provider (or vice versa); a test kernel build emitting an extra variant; mixed-version deployments after an update.

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/f3e1c7a4138bf591. Report an issue: GitHub.