astrid-runtime/astrid · error

FSKit launch lease does not match the kernel manifest

Error message

FSKit launch lease does not match the kernel manifest

What it means

After decoding lease.json into StorageMountLeaseV1, validate_lease requires it to exactly equal the lease supplied at launch. Mismatch means the launch lease was not the one the kernel admitted, so launch is refused to prevent replay or forged leases.

Solutions

  1. Reload the admitted lease from resource_path/lease.json and launch with exactly that struct
  2. Re-run the lease issuance flow so the in-memory lease matches the on-disk manifest
  3. Stop mutating lease fields between issuance and launch

Example fix

// before
let lease = cached_lease.clone(); // stale vs disk
// after
let lease: StorageMountLeaseV1 = serde_json::from_slice(&std::fs::read(resource.join("lease.json"))?)?;
Defensive patterns

Strategy: validation

Validate before calling

fn matches_manifest(lease: &StorageMountLeaseV1) -> anyhow::Result<bool> {
    let on_disk: StorageMountLeaseV1 =
        serde_json::from_slice(&std::fs::read(lease.resource_path.join("lease.json"))?)?;
    Ok(on_disk == *lease)
}

Try / catch

match provider.run(launch) {
    Err(e) if e.to_string().contains("does not match the kernel manifest") => {
        reload_lease_from_disk()?;
        retry_launch()
    }
    r => r,
}

Prevention

When it happens

Trigger: validate_lease compares the parsed manifest to the caller-supplied lease and any field differs (token, paths, expiry, mount_id, etc.) when called via validate_launch or live_managed_callback_lease_is_accepted.

Common situations: Reusing an old in-memory lease while the kernel refreshed lease.json on disk; mutating a lease field after issuance; two concurrent launches with different leases over the same resource_path.

Understand the failure class

Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at crates/astrid-storage-provider-fskit/src/service.rs:177

    #[cfg(not(target_os = "macos"))]
    if lease.callback_path != lease.resource_path.join("control.sock") {
        bail!("FSKit callback path is not the kernel lease endpoint");
    }
    platform_fs::validate_private_directory(&lease.resource_path)
        .context("validate private FSKit lease resource")?;
    platform_fs::verify_no_redirects(&lease.resource_path)
        .context("reject redirected FSKit lease resource")?;
    platform_fs::validate_private_file(&lease.resource_path.join("lease.json"))
        .context("validate private FSKit lease manifest")?;
    let manifest = std::fs::read(lease.resource_path.join("lease.json"))
        .context("read FSKit lease manifest")?;
    if manifest.len() > 64 * 1024 {
        bail!("FSKit lease manifest exceeds the bounded size");
    }
    let admitted: astrid_core::storage_filesystem::StorageMountLeaseV1 =
        serde_json::from_slice(&manifest).context("decode FSKit lease manifest")?;
    if admitted != *lease {
        bail!("FSKit launch lease does not match the kernel manifest");
    }
    Ok(())
}

fn validate_control_path(control_path: &Path, resource_path: &Path) -> Result<()> {
    if !control_path.is_absolute()
        || control_path
            .components()
            .any(|component| matches!(component, std::path::Component::ParentDir))
    {
        bail!("FSKit service control path is malformed");
    }
    let parent = control_path
        .parent()
        .context("FSKit service control path has no parent")?;
    platform_fs::validate_private_directory(parent)
        .context("validate private FSKit control parent")?;
    platform_fs::verify_no_redirects(control_path)

View on GitHub (pinned to affd8760f4)