astrid-runtime/astrid · error

FUSE service returned an incompatible status response

Error message

FUSE service returned an incompatible status response

What it means

This error means the live FUSE service answered a status query with `ControlResponse::Done`, which cannot carry the required access/status information. The sync path expects `Status`; `Done` indicates the service is shutting down or responding with an incompatible protocol shape. It is thrown in main.rs:365 in the status match after the access-equality arm.

Source

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

        },
    }
}

async fn sync(
    client: &mut AdminClient,
    acting_principal: &astrid_core::PrincipalId,
    selector: &StorageMountSelectorV1,
) -> Result<StorageProviderSuccessV1> {
    let record = registry::resolve_record(selector)?;
    let status = require_live_lease(client, acting_principal, &record).await?;
    validate_record(&record, &status)?;
    let control = live_control_status(client, acting_principal, &record).await?;
    match control {
        ControlResponse::Status { access } if access == record.access => {},
        ControlResponse::Status { access } => {
            bail!("detached FUSE service access {access:?} does not match lease")
        },
        ControlResponse::Done => bail!("FUSE service returned an incompatible status response"),
        ControlResponse::Failure { code, message } => {
            bail!("FUSE service status failed [{code}]: {message}")
        },
    }
    into_success(
        client
            .request(AdminRequestKind::StorageMountSync {
                mount_id: record.mount_id,
            })
            .await?,
    )?;
    Ok(StorageProviderSuccessV1::Synced {
        mount_id: record.mount_id,
    })
}

async fn status(
    client: &mut AdminClient,

View on GitHub (pinned to affd8760f4)

Solutions

  1. Verify the service process is alive; if it exited, clean artifacts and remount from the lease.
  2. Re-run the status/sync after confirming the service is fully started and stable.
  3. Remove stale control sockets so a foreign or dead peer cannot answer.
  4. Align crate versions between the admin client and the service so response variants agree.
Defensive patterns

Strategy: try-catch

Type guard

fn is_status(control: &ControlResponse) -> bool {
    matches!(control, ControlResponse::Status { .. })
}

Try / catch

match live_control_status(client, principal, &record).await {
    ControlResponse::Status { .. } => { /* proceed */ }
    ControlResponse::Done => { /* service gone: cleanup + remount */ }
    _ => { /* handle Failure / mismatch */ }
}

Prevention

When it happens

Trigger: The status match arm `ControlResponse::Done` is hit — the service replied with Done instead of `Status { access }` when `live_control_status` queried it.

Common situations: The service exited or is mid-shutdown while the admin client queries it; a stale socket answered by a different process; version skew changing which ControlResponse variant is emitted for status queries.

Related errors


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