astrid-runtime/astrid · critical
detached FUSE service returned a mismatched lease identity
Error message
detached FUSE service returned a mismatched lease identity
What it means
After launching the detached FUSE service, the parent reads the service's Ready reply and verifies that the mount_id and access mode match the StorageMountLeaseV1 it granted. A mismatch means the reply did not correspond to this launch — a protocol or identity corruption — so the mount is rolled back via rollback_mount_error. This protects against mounting with the wrong lease (wrong tenant or access level).
Source
Thrown at crates/astrid-storage-provider-fuse/src/main.rs:255
})
.await?;
let lease = lease_from_response(body)?;
let control_path = registry::control_path(&lease.mount_id)?;
let launch = ServiceLaunch {
lease: lease.clone(),
requested_by: acting_principal,
mountpoint: mountpoint.clone(),
auto_created_mountpoint: auto_created,
};
let startup = launch_service(&launch, &control_path).await;
let ready = match startup {
Ok(ready) => ready,
Err(error) => {
return Err(rollback_mount_error(error, client, &launch, &control_path).await);
},
};
if ready.mount_id != lease.mount_id || ready.access != lease.access {
let error = anyhow::anyhow!("detached FUSE service returned a mismatched lease identity");
return Err(rollback_mount_error(error, client, &launch, &control_path).await);
}
if ready.pid == 0 {
let error = anyhow::anyhow!("detached FUSE service returned an invalid process identity");
return Err(rollback_mount_error(error, client, &launch, &control_path).await);
}
let control_ready = call_control(
&control_path,
&ControlRequest::Status {
requested_by: launch.requested_by.clone(),
},
)
.and_then(|response| require_ready_control_response(response, lease.access));
if let Err(error) = control_ready {
let error = error.context("detached FUSE service failed its readiness handshake");
return Err(rollback_mount_error(error, client, &launch, &control_path).await);
}
let record = registry::MountRecord {View on GitHub (pinned to affd8760f4)
Solutions
- Ensure each detached launch uses a unique, freshly created launch/control path per mount.
- Kill and remove stale service processes and sockets from prior runs before remounting.
- Align host and provider binary versions so the Ready payload schema matches.
- Retry the mount after cleanup; the rollback has already released the bad mount.
Example fix
// before
let control_path = std::env::temp_dir().join("astrid-fuse-control");
// after
let control_path = std::env::temp_dir().join(format!("astrid-fuse-control-{}", uuid::Uuid::new_v4())); Defensive patterns
Strategy: validation
Validate before calling
fn ready_matches(ready: &Ready, lease: &StorageMountLeaseV1) -> bool {
ready.mount_id == lease.mount_id && ready.access == lease.access
} Type guard
fn is_valid_ready(ready: &Ready, lease: &StorageMountLeaseV1) -> bool {
ready.mount_id == lease.mount_id
&& ready.access == lease.access
&& ready.pid != 0
} Try / catch
if ready.mount_id != lease.mount_id || ready.access != lease.access {
let error = anyhow::anyhow!("detached FUSE service returned a mismatched lease identity");
return Err(rollback_mount_error(error, client, &launch, &control_path).await);
} Prevention
- Use a unique per-mount launch/control path (e.g. UUID suffix) to avoid cross-talk between concurrent mounts.
- Clean up stale sockets and launch files from crashed runs before remounting.
- Keep host and provider binaries version-aligned so Ready payloads match the expected schema.
When it happens
Trigger: call_launch -> detached service responds with Ready whose mount_id != lease.mount_id or access != lease.access; caused by stale control sockets, a reused launch file, or a service binary at a different version replying with foreign identity data.
Common situations: Concurrent mounts overwriting each other's launch/control paths in a shared temp dir; stale sockets from a previous crashed run; version skew between host and provider binary.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- mount rollback left the lease registered for recovery; {}
- detached FUSE service readiness access {access:?} does not m
- detached FUSE service access {access:?} does not match lease
- detached FUSE service exceeded the startup response size
- detached FUSE service returned an invalid process identity
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/629701cb15d852b4.
Report an issue: GitHub.