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
- Remove the stale lease.json from resource_path and relaunch so the kernel writes a manifest matching the current lease
- Compare the on-disk lease.json with the kernel-issued lease fields (resource, mountpoint, callback) to identify which field diverged
- Ensure each launch uses a unique resource_path so manifests from prior launches cannot be compared against a new lease
- 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
- Use a unique resource_path per launch
- Never reuse a lease directory across launches
- Let the kernel write manifests exclusively
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
- branding.accent-color
- branding.icon is bytes — distros must not embed assets…
- branding.primary-color
- cannot unmount a relative mountpoint
- capsule archive contains duplicate entry
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)