astrid-runtime/astrid · error
detached FUSE service failed: {message}
Error message
detached FUSE service failed: {message} What it means
This wraps a structured failure reported by the FUSE service itself. The child mounted nothing, sent ServiceStartup::Error { message } over stdout, and the parent re-raises that message prefixed with context. The root cause text after the colon comes from inside the service (FUSE mount failure, permission denied on the mountpoint, kernel registration rejection, etc.).
Source
Thrown at crates/astrid-storage-provider-fuse/src/main.rs:724
match serde_json::from_str(&line)? {
ServiceStartup::Ready {
mount_id,
pid,
access,
} => {
if !control_path.exists() {
bail!("detached FUSE service did not retain its control endpoint");
}
if pid == 0 {
bail!("detached FUSE service returned an invalid process identity");
}
Ok(ControlReady {
mount_id,
pid,
access,
})
},
ServiceStartup::Error { message } => bail!("detached FUSE service failed: {message}"),
}
}
#[derive(Debug)]
struct ControlReady {
mount_id: StorageMountId,
pid: u32,
access: StorageProviderAccessV1,
}
#[derive(Debug, Deserialize)]
struct LeaseStatus {
#[allow(dead_code)]
mount_id: StorageMountId,
access: StorageProviderAccessV1,
mountpoint: PathBuf,
dirty: bool,
}View on GitHub (pinned to affd8760f4)
Solutions
- Read the embedded {message} in the error — it names the service-side root cause; fix that directly
- Verify the mountpoint exists, is an empty directory, and is not already mounted
- Check FUSE availability: fuse kernel module loaded, fusermount3 installed, unprivileged mounts enabled
- Confirm parent and service binaries are from the same version so the launch JSON deserializes
Example fix
null
Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-flight checks before launching the service
if !mountpoint.exists() { return Err(anyhow!("mountpoint {} does not exist", mountpoint.display())); }
if mountpoint_is_busy(mountpoint)? { return Err(anyhow!("mountpoint already in use")); }
ensure_fuse_available()?; // fusermount3 present, module loaded, unprivileged mounts allowed Try / catch
match start_detached_service(&launch).await {
Err(e) if e.to_string().contains("detached FUSE service failed:") => {
let cause = e.to_string().split("detached FUSE service failed: ").nth(1).unwrap_or("");
eprintln!("service-side failure: {cause}"); // act on the embedded root cause
}
Err(e) => return Err(e),
Ok(ready) => use_mount(ready),
} Prevention
- Read the embedded message after the prefix — it names the actual service-side cause
- Pre-create the mountpoint directory and ensure it is empty and writable
- Verify FUSE prerequisites: kernel module loaded, fusermount3 installed, unprivileged_userfusermount enabled
- Keep provider and kernel versions aligned so the launch config deserializes in the service
When it happens
Trigger: The detached FUSE service fails during startup and deliberately reports it: fuse mount syscall fails, mountpoint doesn't exist or is busy, kernel storage-mount lease cannot be acquired, launch config deserialization fails inside the service.
Common situations: Mountpoint directory missing or already in use; fusermount/fuse kernel module unavailable or unprivileged user mounts disabled (/proc/sys/fs/unprivileged_userfusermount); stale registry entry pointing at a dead lease; malformed launch JSON from a version mismatch.
Related errors
- candidate generation for '{id}' exited before signaling read
- FUSE mount completed but is absent from the Linux mount tabl
- FUSE service status failed [{code}]: {message}
- mount was issued to another acting principal
- detached FUSE service exceeded the startup response size
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/a4fc4b1d6fad81eb.
Report an issue: GitHub.