astrid-runtime/astrid · error

WinFsp service parent PID is invalid

Error message

WinFsp service parent PID is invalid

What it means

validate_service_launch rejects the parent PID if it is <= 1 or equals the service's own process ID (std::process::id()). A parent PID of 0/1 cannot be a real launching parent, and self-reference would make the liveness check meaningless. This guards the parent-liveness handshake against corrupted or forged launch data.

Source

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

    };
    let mut stdout = std::io::stdout().lock();
    serde_json::to_writer(&mut stdout, &ready).context("encode WinFsp readiness")?;
    stdout
        .write_all(b"\n")
        .context("terminate WinFsp readiness response")?;
    stdout.flush().context("flush WinFsp readiness")?;

    let result = private_service_loop(filesystem, listener, &launch).await;
    let _ = local_transport::remove_endpoint(&launch.control_path);
    result
}

fn validate_service_launch(launch: &StorageProviderServiceLaunchV1) -> Result<()> {
    if launch.schema != STORAGE_FILESYSTEM_SERVICE_LAUNCH_SCHEMA_V1 {
        bail!("unsupported WinFsp service launch schema {}", launch.schema);
    }
    if launch.parent.pid <= 1 || launch.parent.pid == std::process::id() {
        bail!("WinFsp service parent PID is invalid");
    }
    if launch.parent.token.len() < 16
        || launch.parent.token.len() > 512
        || launch.parent.token.chars().any(char::is_control)
    {
        bail!("WinFsp service parent token is invalid");
    }
    if let Some(identity) = launch.parent.start_identity.as_deref()
        && (identity.is_empty() || identity.len() > 512 || identity.chars().any(char::is_control))
    {
        bail!("WinFsp service parent start identity is invalid");
    }
    if launch.parent.start_identity.is_none() {
        bail!("WinFsp service parent start identity is required on Windows");
    }
    let lease = &launch.lease;
    let now = SystemTime::now()
        .duration_since(UNIX_EPOCH)

View on GitHub (pinned to affd8760f4)

Solutions

  1. Have the parent serialize std::process::id() (a real, live PID) into launch.parent.pid before spawning the service
  2. Fix test harnesses to inject a plausible PID (e.g. the test process's own parent, not 0/1)
  3. Validate the struct is fully populated before writing the launch document
  4. Confirm field order/naming matches the schema if building the JSON by hand

Example fix

// before
let launch = StorageProviderServiceLaunchV1::default(); // parent.pid = 0
// after
let mut launch = StorageProviderServiceLaunchV1::default();
launch.parent.pid = std::process::id();
Defensive patterns

Strategy: validation

Validate before calling

if launch.parent.pid <= 1 || launch.parent.pid == std::process::id() {
    return Err(format!("invalid parent PID {}", launch.parent.pid));
}

Type guard

fn has_plausible_parent_pid(launch: &StorageProviderServiceLaunchV1) -> bool {
    launch.parent.pid > 1 && launch.parent.pid != std::process::id()
}

Try / catch

match service_err {
    Err(e) if e.to_string().contains("parent PID is invalid") => {
        eprintln!("populate launch.parent.pid from the live parent process");
    }
    other => other?,
}

Prevention

When it happens

Trigger: The launch document contains parent.pid of 0, 1, or the service's own PID — e.g. the parent serialized an uninitialized/default PID, a test harness hard-coded pid 0, or PID fields were reordered during (de)serialization.

Common situations: Default-initialized StorageProviderServiceLaunch structs in tests; hand-written launch JSON with a placeholder PID; a parent process re-exec trick that made the recorded PID invalid.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


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