astrid-runtime/astrid · error
mount rollback left the lease registered for recovery; {}
Error message
mount rollback left the lease registered for recovery; {} What it means
During rollback after a failed mount, rollback_after_native_failure could not unmount the native filesystem (native_unmounted == false), so the storage-mount lease remains registered in the kernel and only background recovery can clean it up. The bail reports the accumulated step errors (unmount/inspect) joined with '; '.
Source
Thrown at crates/astrid-storage-provider-fskit/src/main.rs:340
async fn revoke_after_registry_failure(client: &mut AdminClient, mount_id: StorageMountId) {
let _ = client
.request(AdminRequestKind::StorageMountRevoke { mount_id })
.await;
}
fn with_native_rollback(
error: anyhow::Error,
rollback: Result<()>,
) -> Result<StorageProviderSuccessV1> {
match rollback {
Ok(()) => Err(error),
Err(rollback) => Err(error).context(rollback),
}
}
fn rollback_outcome(native_unmounted: bool, errors: &[String]) -> Result<()> {
if !native_unmounted {
bail!(
"mount rollback left the lease registered for recovery; {}",
errors.join("; ")
);
}
if errors.is_empty() {
return Ok(());
}
bail!("mount rollback incomplete: {}", errors.join("; "))
}
async fn rollback_after_native_failure(
client: &mut AdminClient,
mount_id: &StorageMountId,
mountpoint: &Path,
auto_created: bool,
native_mount_command_succeeded: bool,
) -> Result<()> {
let mut errors = Vec::new();View on GitHub (pinned to affd8760f4)
Solutions
- Free the mount: close processes holding files under the mountpoint, then unmount manually (e.g. diskutil unmount on macOS).
- Check native_mount_is_active for the path; if still mounted, retry unmount until it succeeds, then revoke the lease via StorageMountRevoke.
- Let kernel-side lease recovery expire the stale lease if manual unmount is impossible, then clean the registry entry.
- Re-run the mount operation afterwards; stale recovery on next unmount will handle leftover leases if authorize_stale_cleanup permits it.
Defensive patterns
Strategy: try-catch
Validate before calling
// before mounting, ensure no process holds the mountpoint
let busy = std::process::Command::new("lsof").arg(&mountpoint).status().map(|s| s.success()).unwrap_or(false);
if busy { return Err(anyhow!("mountpoint is busy; aborting mount")); } Try / catch
match rollback_after_native_failure(&mut client, &mount_id, &mountpoint, auto_created, mounted).await {
Err(e) if e.to_string().contains("left the lease registered for recovery") => {
// retry native unmount after releasing busy resources, then revoke lease explicitly
},
other => { /* proceed */ },
} Prevention
- Ensure no open file handles or watchers under the mountpoint before mount/unmount.
- Monitor the fskit daemon so it does not die mid-operation.
- After this error, run manual unmount + StorageMountRevoke to converge state.
- Rely on the registry's stale-recovery path for leases you cannot revoke immediately.
When it happens
Trigger: rollback_after_native_failure() runs after a mount attempt fails partway; native_unmount(mountpoint) or native_mount_is_active(mountpoint) errors out (e.g. fskit process crashed, mount is busy, macOS refuses detach), so rollback_outcome(false, errors) bails.
Common situations: A file under the mount is open by another process, making unmount return EBUSY; fskit daemon died so the native mount is in an unknown state; unmount tooling unavailable mid-rollback.
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
- kernel refused storage unmount authorization: {error}
- detached FUSE service returned a mismatched lease identity
- kernel refused storage lifecycle request: {error}
- kernel returned an unexpected storage unmount response
- mount rollback incomplete: {}
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/c2250c60a951c931.
Report an issue: GitHub.