astrid-runtime/astrid · error
WinFsp service parent start identity is invalid
Error message
WinFsp service parent start identity is invalid
What it means
The WinFsp mount service validates that the launching parent supplied a start_identity string. This error fires when start_identity is present (Some) but fails sanity checks: it is empty, longer than 512 bytes, or contains Unicode control characters. The library rejects it before starting the filesystem because the identity is used for service-attribution/audit and an unbounded or control-character-laden value is treated as a malformed or hostile launch descriptor.
Source
Thrown at crates/astrid-storage-provider-winfsp/src/win.rs:252
}
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)
.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")View on GitHub (pinned to affd8760f4)
Solutions
- In the launching parent, set start_identity to a non-empty, trimmed string no longer than 512 chars; if there is no identity, serialize None rather than an empty string.
- Strip control characters and trim the identity before building the launch descriptor (retain char::is_control filter).
- Log/inspect the exact identity bytes being written to the launch file to find where control characters or overlong values originate.
- If the identity legitimately needs more room, shorten it (e.g. store an ID/reference, not a full description) since 512 is a hard limit in this validator.
Example fix
// before
parent.start_identity = Some(format!("{}\n{}", user, host));
// after
let identity: String = format!("{} {}", user, host).chars().filter(|c| !c.is_control()).collect();
parent.start_identity = if identity.is_empty() || identity.len() > 512 { None } else { Some(identity) }; Defensive patterns
Strategy: validation
Validate before calling
fn valid_start_identity(s: &Option<String>) -> bool {
match s {
Some(s) => !s.is_empty() && s.len() <= 512 && !s.chars().any(char::is_control),
None => false,
}
}
assert!(valid_start_identity(&launch.parent.start_identity), "invalid start_identity"); Type guard
fn is_ok_identity(s: Option<&str>) -> bool {
matches!(s, Some(v) if !v.is_empty() && v.len() <= 512 && !v.chars().any(char::is_control))
} Prevention
- Trim and filter control characters from identity strings at config load time
- Never serialize an empty string where None is meant
- Enforce the 512-char limit in the launcher with a unit test
- Log the identity length/content type (not value) when building launch descriptors
When it happens
Trigger: service_main -> validate_service_launch receives a StorageProviderServiceLaunchV1 whose launch.parent.start_identity is Some(s) where s.is_empty(), s.len() > 512, or s.chars().any(char::is_control). I.e., the parent process serialized a non-empty but invalid identity string into the launch descriptor.
Common situations: A launcher passes "" (empty string) instead of None when the identity is unknown; a config/registry field for the mount identity accumulates whitespace/newlines or other control chars; a truncated or concatenated identity from an IPC buffer exceeds 512 chars; templates that interpolate an account name into the identity pick up stray \0 or \r\n.
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
- WinFsp daemon lease exceeds limit
- WinFsp daemon lease contains a relative endpoint
- WinFsp service launch exceeds limit
- WinFsp service parent process is not alive
- WinFsp service parent PID is invalid
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/a63ca385a0548574.
Report an issue: GitHub.