astrid-runtime/astrid · error

FUSE callback response exceeds the bounded frame size

Error message

FUSE callback response exceeds the bounded frame size

What it means

read_callback_response() reads a 4-byte big-endian length prefix followed by a JSON body over the local callback stream. If the declared frame length is 0 or exceeds MAX_CALLBACK_BYTES, it refuses to allocate and bails, protecting the provider from unbounded allocations on the local stream.

Source

Thrown at crates/astrid-storage-provider-fuse/src/service.rs:331

    stream.flush().await?;
    let response = read_callback_response(&mut stream).await?;
    if response.request_id != request.request_id {
        bail!("FUSE callback probe correlation mismatch");
    }
    match response.outcome {
        StorageFilesystemOutcomeV2::Success(_) => Ok(()),
        StorageFilesystemOutcomeV2::Failure(StorageFilesystemFailureV1 { code, message }) => {
            bail!("FUSE callback probe failed [{code}]: {message}")
        },
    }
}

async fn read_callback_response(stream: &mut LocalStream) -> Result<StorageFilesystemResponseV2> {
    let mut length = [0_u8; 4];
    stream.read_exact(&mut length).await?;
    let length = u32::from_be_bytes(length) as usize;
    if length == 0 || length > MAX_CALLBACK_BYTES {
        bail!("FUSE callback response exceeds the bounded frame size");
    }
    let mut bytes = vec![0_u8; length];
    stream.read_exact(&mut bytes).await?;
    let response: StorageFilesystemResponseV2 =
        serde_json::from_slice(&bytes).context("decode FUSE callback probe")?;
    if response.protocol_version != STORAGE_FILESYSTEM_PROTOCOL_V2 {
        bail!("FUSE callback probe protocol mismatch");
    }
    Ok(response)
}

#[cfg(unix)]
fn parent_is_alive(
    parent: &astrid_core::storage_filesystem::StorageProviderParentLifetimeV1,
) -> bool {
    use nix::sys::signal::kill;
    use nix::unistd::Pid;

View on GitHub (pinned to affd8760f4)

Solutions

  1. Check the FUSE provider callback peer is the correct, matching-version process speaking the length-prefixed STORAGE_FILESYSTEM_PROTOCOL_V2 framing.
  2. Restart the callback peer / relaunch the provider so both ends start with a clean stream state.
  3. If legitimate responses are too large, raise MAX_CALLBACK_BYTES on both sides consistently.
  4. Log the offending length value to confirm whether the peer is writing garbage or genuinely oversized payloads.
Defensive patterns

Strategy: validation

Validate before calling

// On the peer side, before writing:
let bytes = serde_json::to_vec(&response)?;
assert!(bytes.len() > 0 && bytes.len() <= MAX_CALLBACK_BYTES, "callback frame out of bounds");

Try / catch

// Rust
match probe_callback(&mut stream, request).await {
    Err(e) if e.to_string().contains("bounded frame size") => {
        // restart the peer / relaunch; the stream framing is desynchronized
    }
    other => other?,
}

Prevention

When it happens

Trigger: The peer on the LocalStream writes a length prefix of 0 or one greater than MAX_CALLBACK_BYTES before the response body — e.g. a corrupted writer, a peer that isn't speaking the framed protocol, or a response payload that legitimately exceeds the bound.

Common situations: A stale or mismatched process is attached to the local stream; the callback peer crashed mid-frame and wrote garbage; protocol drift between provider versions makes the reader interpret a non-length field as the frame size.

Understand the failure class

Background: payload too large / request exceeds maximum size: why libraries cap bytes and how to fix oversize payloads — this error's family across 50 libraries.

Related errors


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