astrid-runtime/astrid · error

registered FUSE service access

Error message

registered FUSE service access {access:?} does not match its lease

What it means

When remounting a storage volume, the FUSE provider queries the already-running FUSE service for its status and compares the reported access identity with the access recorded in the existing mount lease. If a Status response comes back but the access does not match the lease, the mount state is inconsistent and the operation is aborted with this bail in crates/astrid-storage-provider-fuse/src/main.rs:823.

Solutions

  1. Unmount the stale FUSE service (or kill the old daemon) and clean up the stale record, then retry the mount
  2. Delete the stale mount record/lease and re-run the mount so a fresh lease with matching access is issued
  3. Verify the acting principal matches the one that originally mounted the volume

Example fix

// before: retrying mount while a mismatched service is alive
mount_storage(...)?; // panics/bails: access does not match its lease
// after
unmount_storage(...).ok(); // tear down stale service first
mount_storage(...)?;
Defensive patterns

Strategy: validation

Validate before calling

fn access_matches_lease(status_access: &Access, lease: &StorageMountLeaseV1) -> bool { status_access == &lease.access }

Type guard

fn is_matching_status(resp: &ControlResponse, expected: &Access) -> Option<Access> { match resp { ControlResponse::Status { access } if access == expected => Some(access.clone()), _ => None } }

Try / catch

match ensure_mounted(...) { Err(e) if e.to_string().contains("does not match its lease") => { cleanup_stale_record(...).await?; ensure_mounted(...)? }, r => r? }

Prevention

When it happens

Trigger: Calling the mount/ensure-mounted path while another FUSE service instance is already registered on the control socket, and that instance reports a Status whose access differs from the lease held by the caller (e.g. a stale service from a previous session with different credentials).

Common situations: A leftover FUSE daemon from a crashed prior run is still bound to the control socket; two different OS users or principals mounted the same mountpoint; the lease file was regenerated with different access after the service started.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

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

        return Ok(());
    };
    let status = kernel_lease_status(client, &record.mount_id).await?;
    let Some(status) = status else {
        cleanup_stale_record(client, acting_principal, &record).await?;
        return Ok(());
    };
    validate_record(&record, &status)?;
    match call_control(
        &record.control_path,
        &ControlRequest::Status {
            requested_by: record.requested_by.clone(),
        },
    ) {
        Ok(ControlResponse::Status { access }) if access == status.access => {
            bail!("mountpoint is already mounted: {}", mountpoint.display())
        },
        Ok(ControlResponse::Status { access }) => {
            bail!("registered FUSE service access {access:?} does not match its lease")
        },
        Ok(_) => bail!("registered FUSE service returned an incompatible status response"),
        Err(_) => {
            cleanup_stale_record(client, acting_principal, &record).await?;
            Ok(())
        },
    }
}

async fn cleanup_stale_record(
    client: &mut AdminClient,
    acting_principal: &astrid_core::PrincipalId,
    record: &registry::MountRecord,
) -> Result<()> {
    let lease_is_live = kernel_lease_status(client, &record.mount_id)
        .await?
        .is_some();
    let _ = call_control(

View on GitHub (pinned to affd8760f4)