astrid-runtime/astrid · error

invalid FUSE service parent token

Error message

invalid FUSE service parent token

What it means

The parent's authentication token must be 16–512 bytes long and contain no control characters; it is used by the helper to authenticate Status/Stop control requests. A token that is missing, too short, too long, or contains control characters is rejected before the service starts.

Source

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

fn validate_launch(launch: &StorageProviderServiceLaunchV1) -> Result<()> {
    validate_parent(&launch.parent)?;
    validate_lease(&launch.lease)?;
    validate_mountpoint(&launch.mountpoint, &launch.lease.resource_path)?;
    validate_control_path(&launch.control_path, &launch.lease.resource_path)?;
    Ok(())
}

fn validate_parent(
    parent: &astrid_core::storage_filesystem::StorageProviderParentLifetimeV1,
) -> Result<()> {
    if parent.pid <= 1 || parent.pid == std::process::id() {
        bail!("invalid FUSE service parent PID");
    }
    if parent.token.len() < 16
        || parent.token.len() > 512
        || parent.token.chars().any(char::is_control)
    {
        bail!("invalid FUSE service parent token");
    }
    if let Some(identity) = parent.start_identity.as_deref()
        && (identity.is_empty() || identity.len() > 512 || identity.chars().any(char::is_control))
    {
        bail!("invalid FUSE service parent start identity");
    }
    #[cfg(target_os = "linux")]
    if parent.start_identity.is_none() {
        bail!("FUSE service parent start identity is required on Linux");
    }
    Ok(())
}

fn validate_lease(lease: &StorageMountLeaseV1) -> Result<()> {
    if lease.lease_token.len() < 16
        || lease.lease_token.len() > 4096
        || lease.lease_token.chars().any(char::is_control)
    {

View on GitHub (pinned to affd8760f4)

Solutions

  1. Generate a token with a CSPRNG of at least 16 bytes (e.g. 32 random bytes hex/base64).
  2. Trim and sanitize the token so it contains no control characters (strip \n, \r, \0).
  3. Verify the token is passed intact to the child process (env/args, not truncated).
  4. Validate token length client-side before building the launch descriptor.

Example fix

// before
let token = "abc"; // too short
// after
use rand::RngCore;
let mut buf = [0u8; 32];
rand::thread_rng().fill_bytes(&mut buf);
let token = hex::encode(buf); // 64 chars, no control chars
Defensive patterns

Strategy: validation

Validate before calling

fn valid_token(token: &str) -> bool {
    (16..=512).contains(&token.len()) && !token.chars().any(char::is_control)
}

Type guard

fn has_valid_token(parent: &StorageProviderParentLifetimeV1) -> bool {
    (16..=512).contains(&parent.token.len()) && !parent.token.chars().any(char::is_control)
}

Prevention

When it happens

Trigger: `validate_parent` finds `parent.token.len() < 16 || > 512 || contains control chars` when `validate_launch` checks the launch descriptor.

Common situations: Caller generated an empty or too-short token; a token was read from a file/env with a trailing newline or other control bytes; truncated token from config; placeholder token left in test config.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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