astrid-runtime/astrid · error

WinFsp lease paths are malformed

Error message

WinFsp lease paths are malformed

What it means

The lease declares a resource_path (private state directory) and a callback_path for its control endpoint. The validator requires both to be absolute and requires callback_path to be exactly resource_path joined with "control.endpoint". Any deviation — relative paths, a moved or renamed callback path, or a resource/callback mismatch — is rejected as malformed before the mount starts.

Solutions

  1. Regenerate the launch descriptor so callback_path is computed as resource_path.join("control.endpoint") rather than set independently.
  2. Canonicalize both paths (dunce::canonicalize or fs::canonicalize) before storing them so prefixes and separators match exactly.
  3. Fix launchers that relocate the resource directory to rewrite callback_path (and control_path) at the same time.
  4. Validate at descriptor-build time: assert resource_path.is_absolute() && callback_path == resource_path.join("control.endpoint").

Example fix

// before
lease.callback_path = PathBuf::from("control.endpoint");
// after
lease.callback_path = lease.resource_path.join("control.endpoint");
Defensive patterns

Strategy: validation

Validate before calling

let rp = dunce::canonicalize(&lease.resource_path)?;
let cp = dunce::canonicalize(&lease.callback_path)?;
if !rp.is_absolute() || !cp.is_absolute() || cp != rp.join("control.endpoint") {
    return Err(anyhow!("lease paths malformed: callback_path must equal resource_path/control.endpoint"));
}

Prevention

When it happens

Trigger: service_main -> validate_service_launch when lease.resource_path is relative, lease.callback_path is relative, or callback_path != resource_path.join("control.endpoint") (e.g. custom endpoint name, nested subdir, or trailing separators/case differences causing inequality).

Common situations: A launcher rewrites the resource directory (relocation, different drive letter) but leaves callback_path stale; templates that use a custom endpoint filename; building paths from relative working-directory strings instead of canonical absolute paths; path normalization differences (forward slashes, \\?\ prefixes) making semantically equal paths compare unequal.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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

Appendix: source

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

    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)
        .context("read system clock")?
        .as_secs();
    if lease.expires_at_epoch_secs < now {
        bail!("WinFsp lease is expired");
    }
    if lease.lease_token.len() < 16 || lease.lease_token.len() > 4096 {
        bail!("WinFsp lease callback token is invalid");
    }
    if !lease.resource_path.is_absolute()
        || !lease.callback_path.is_absolute()
        || lease.callback_path != lease.resource_path.join("control.endpoint")
    {
        bail!("WinFsp lease paths are malformed");
    }
    platform_fs::validate_private_directory(&lease.resource_path)
        .context("validate private WinFsp lease resource")?;
    platform_fs::verify_no_redirects(&lease.resource_path)
        .context("reject redirected WinFsp lease resource")?;
    let manifest_path = lease.resource_path.join("lease.json");
    platform_fs::validate_private_file(&manifest_path)
        .context("validate private WinFsp lease manifest")?;
    let manifest = std::fs::read(&manifest_path).context("read WinFsp lease manifest")?;
    if manifest.len() > 64 * 1024 {
        bail!("WinFsp lease manifest exceeds the bounded size");
    }
    let admitted: StorageMountLeaseV1 =
        serde_json::from_slice(&manifest).context("decode WinFsp lease manifest")?;
    if admitted != *lease {
        bail!("WinFsp launch lease does not match the kernel manifest");
    }
    if !launch.mountpoint.is_absolute()

View on GitHub (pinned to affd8760f4)