astrid-runtime/astrid · error
FUSE service unmount failed [{code}]: {message}
Error message
FUSE service unmount failed [{code}]: {message} What it means
When unmounting, the FUSE control service can reject the request with a ControlResponse::Failure carrying a code and message. The client propagates that failure as this bail in crates/astrid-storage-provider-fuse/src/main.rs:875, embedding the service-side code and message.
Source
Thrown at crates/astrid-storage-provider-fuse/src/main.rs:875
registry::remove_record(&record.mount_id)?;
cleanup_service_artifacts(
&record.control_path,
&record.mountpoint,
record.auto_created_mountpoint,
)?;
Ok(())
}
fn control_unmount(control_path: &Path, acting_principal: &astrid_core::PrincipalId) -> Result<()> {
match call_control(
control_path,
&ControlRequest::Unmount {
requested_by: acting_principal.clone(),
},
)? {
ControlResponse::Done => Ok(()),
ControlResponse::Failure { code, message } => {
bail!("FUSE service unmount failed [{code}]: {message}")
},
ControlResponse::Status { .. } => {
bail!("FUSE service returned an incompatible unmount response")
},
}
}
fn cleanup_mountpoint(mountpoint: &Path, auto_created: bool) -> Result<()> {
if auto_created
&& !mountpoint::mountinfo_contains(mountpoint)?
&& std::fs::symlink_metadata(mountpoint).is_ok_and(|metadata| metadata.is_dir())
&& std::fs::read_dir(mountpoint)?.next().is_none()
{
let _ = std::fs::remove_dir(mountpoint);
}
Ok(())
}
View on GitHub (pinned to affd8760f4)
Solutions
- Read the embedded [code] and {message} from the error to identify the service-side cause and fix that first (e.g. close files, correct principal)
- Retry the unmount after ensuring no processes hold open files under the mountpoint (fuser -v <mountpoint>)
- If the service is stale, force-terminate the FUSE daemon and clean up the mountpoint/record manually, then remount cleanly
Example fix
// before unmount(...)?; // FUSE service unmount failed [EBUSY]: device busy // after ensure_no_open_handles(mountpoint)?; // e.g. run fuser/lsof check unmount(...)?;
Defensive patterns
Strategy: try-catch
Validate before calling
if has_open_handles(mountpoint) { bail!("close handles before unmount") } Type guard
fn is_failure(resp: &ControlResponse) -> Option<(u32, String)> { match resp { ControlResponse::Failure { code, message } => Some((*code, message.clone())), _ => None } } Try / catch
match unmount(...) { Err(e) if e.to_string().starts_with("FUSE service unmount failed") => { log_service_code(&e); handle_service_failure(&e) }, r => r? } Prevention
- Close all files under the mountpoint before unmounting
- Unmount with the same principal that mounted
- Check service logs for the embedded failure code
When it happens
Trigger: Calling the unmount path while the FUSE service refuses the Unmount request — e.g. the mountpoint is still busy, the requesting principal (requested_by) is not authorized, or the service has no active mount.
Common situations: Open file handles keep the mount busy; a different user tries to unmount another principal's mount; the kernel-level FUSE mount already died but the service still tracks it.
Related errors
- detached FUSE service readiness failed [{code}]: {message}
- FUSE service returned an incompatible unmount response
- lazy unmount {}: {error}
- opaque capsule assets cannot be symlinks: {}
- kernel refused storage unmount authorization: {error}
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/1554d7328640e3eb.
Report an issue: GitHub.