astrid-runtime/astrid · error

WinFsp callback probe failed

Error message

WinFsp callback probe failed [{code}]: {message}

What it means

When the callback responder reports a Failure outcome, probe_callback surfaces it as a bail formatted as 'WinFsp callback probe failed [{code}]: {message}'. This is the propagated error from the storage filesystem side of the probe — the daemon itself worked, but the operation it validated failed.

Solutions

  1. Read the interpolated code and message in the final error text and fix the underlying responder-side cause (credentials, resource existence, permissions).
  2. Retry after resolving the backend condition (e.g. re-authenticate, restore the resource).
  3. Check responder logs for the original failure stack, since this error only forwards code/message.
  4. Ensure the lease resource_path still exists and is accessible before launching the service.
Defensive patterns

Strategy: try-catch

Try / catch

match probe_callback(&launch, &request).await {
    Err(e) => {
        let msg = e.to_string();
        if let Some(inner) = msg.strip_prefix("WinFsp callback probe failed [") {
            let (code, detail) = inner.split_once("]").map(|(c, d)| (c, &d[2..])).unwrap();
            log::error!("backend probe failure code={code}: {detail}");
        }
        Err(e)
    },
    Ok(()) => Ok(()),
}

Prevention

When it happens

Trigger: run_private_service -> probe_callback where the StorageFilesystemResponseV2.outcome is Failure(StorageFilesystemFailureV1 { code, message }); code and message come from the responder (e.g. auth failure, missing resource, backend error).

Common situations: Backend storage unavailable or credentials expired when the WinFsp mount validated its filesystem; the probed resource was deleted between lease creation and probe; responder-side permission denial on the mount root.

Related errors


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

Appendix: source

Thrown at crates/astrid-storage-provider-winfsp/src/win.rs:374

    stream.read_exact(&mut response_length).await?;
    let length = u32::from_be_bytes(response_length) as usize;
    if length == 0 || length > SERVICE_MAX_CALLBACK_BYTES {
        bail!("WinFsp callback response exceeds limit");
    }
    let mut response_bytes = vec![0_u8; length];
    stream.read_exact(&mut response_bytes).await?;
    let response: StorageFilesystemResponseV2 =
        serde_json::from_slice(&response_bytes).context("decode WinFsp callback probe")?;
    if response.protocol_version != STORAGE_FILESYSTEM_PROTOCOL_V2 {
        bail!("WinFsp callback probe protocol mismatch");
    }
    if response.request_id != request.request_id {
        bail!("WinFsp callback probe correlation mismatch");
    }
    match response.outcome {
        StorageFilesystemOutcomeV2::Success(_) => Ok(()),
        StorageFilesystemOutcomeV2::Failure(StorageFilesystemFailureV1 { code, message }) => {
            bail!("WinFsp callback probe failed [{code}]: {message}")
        },
    }
}

async fn private_service_loop(
    filesystem: FileSystem,
    listener: local_transport::LocalListener,
    launch: &StorageProviderServiceLaunchV1,
) -> Result<()> {
    let mut filesystem = Some(filesystem);
    let mut poll = tokio::time::interval(SERVICE_POLL);
    loop {
        tokio::select! {
            accepted = local_transport::accept(&listener) => {
                let mut stream = accepted.context("accept WinFsp service control")?;
                let request = read_service_control(&mut stream).await?;
                let (response, stop) = match request {
                    ServiceControlRequest::Status { token } if token == launch.parent.token => {

View on GitHub (pinned to affd8760f4)