astrid-runtime/astrid · error
registered FUSE service returned an incompatible status resp
Error message
registered FUSE service returned an incompatible status response
What it means
During mount, the FUSE control channel is expected to answer a status probe with a ControlResponse::Status. If the service replies with some other ControlResponse variant (Done, Failure, etc.), the code cannot determine mount state and bails with this message in crates/astrid-storage-provider-fuse/src/main.rs:825.
Source
Thrown at crates/astrid-storage-provider-fuse/src/main.rs:825
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: ®istry::MountRecord,
) -> Result<()> {
let lease_is_live = kernel_lease_status(client, &record.mount_id)
.await?
.is_some();
let _ = call_control(
&record.control_path,
&ControlRequest::Unmount {View on GitHub (pinned to affd8760f4)
Solutions
- Ensure the process on the control socket is the matching-version astrid FUSE service; kill or upgrade it if not
- Remove stale socket files left by previous runs and retry the mount
- Align client and service versions so ControlResponse semantics match
Example fix
// before: probing an unknown process on the socket let status = query_status(socket)?; // bails on non-Status reply // after ensure_fuse_service_running(socket)?; // verify the right service owns the socket let status = query_status(socket)?;
Defensive patterns
Strategy: type-guard
Validate before calling
let ok = matches!(resp, ControlResponse::Status { .. }); Type guard
fn as_status(resp: &ControlResponse) -> Option<&Access> { match resp { ControlResponse::Status { access } => Some(access), _ => None } } Try / catch
match result { Err(e) if e.to_string().contains("incompatible status response") => restart_fuse_service()?, r => r? } Prevention
- Pin client and service to the same version
- Check socket ownership before probing
- Clean stale sockets at startup
When it happens
Trigger: Sending a status query over the FUSE control socket and receiving a non-Status response — typically because the listening process is not the expected FUSE control service or speaks a different protocol version.
Common situations: Protocol/version mismatch between the mount client and a running FUSE service; another program occupies the control socket path; an older service binary that lacks the Status response.
Related errors
- FUSE service returned an incompatible unmount response
- unexpected capsule metadata response: {other:?}
- unexpected response from kernel: {body:?}
- unexpected response from kernel: {other:?}
- kernel returned an unexpected storage mount response
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/ed996bcd3d8a2a4a.
Report an issue: GitHub.