astrid-runtime/astrid · error

FUSE launch lease does not match the kernel manifest

Error message

FUSE launch lease does not match the kernel manifest

What it means

After parsing lease.json into StorageMountLeaseV1, validate_lease compares it with the lease supplied by the kernel in the launch request. Any field mismatch between the on-disk manifest and the in-kernel lease aborts the launch, since the kernel manifest is the authoritative record of the mount agreement. This prevents launching a FUSE service against a tampered, stale, or mismatched manifest.

Solutions

  1. Remove the stale lease.json from resource_path and relaunch so the kernel writes a manifest matching the current lease
  2. Compare the on-disk lease.json with the kernel-issued lease fields (resource, mountpoint, callback) to identify which field diverged
  3. Ensure each launch uses a unique resource_path so manifests from prior launches cannot be compared against a new lease
  4. Verify no external process rewrites lease.json between lease issuance and validate_launch

Example fix

// before: reusing a directory whose manifest belongs to an older lease
validate_launch(&old_lease)

// after: fresh resource per lease, manifest regenerated
let resource_path = lease_dir_for(&lease.id); // unique per launch
validate_launch(&lease)
Defensive patterns

Strategy: validation

Validate before calling

let on_disk: StorageMountLeaseV1 = serde_json::from_slice(&std::fs::read(manifest_path)?)?;
if on_disk != expected_lease { /* relaunch with a fresh manifest */ }

Prevention

When it happens

Trigger: Calling validate_launch when the deserialized lease.json on disk is not equal (PartialEq) to the StorageMountLeaseV1 passed in the lease argument — e.g. fields differ after the manifest was edited, replaced, or generated for a different launch.

Common situations: A previous launch's manifest still on disk while the kernel issued a new lease with different mount/resource parameters; the manifest was hand-edited; the resource directory was reused across launches; a race where the manifest is rewritten between launches.

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

Appendix: source

Thrown at crates/astrid-storage-provider-fuse/src/service.rs:238

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

fn validate_mountpoint(mountpoint: &Path, resource_path: &Path) -> Result<()> {
    if !mountpoint.is_absolute()
        || mountpoint
            .components()
            .any(|component| matches!(component, std::path::Component::ParentDir))
        || mountpoint.parent().is_none()
    {
        bail!("FUSE service mountpoint is malformed");
    }
    if mountpoint == resource_path
        || mountpoint.starts_with(resource_path)
        || resource_path.starts_with(mountpoint)
    {
        bail!("FUSE service mountpoint overlaps the lease resource");

View on GitHub (pinned to affd8760f4)