astrid-runtime/astrid · error
WinFsp service parent process is not alive
Error message
WinFsp service parent process is not alive
What it means
run_private_service starts by checking the parent process recorded in the launch (launch.parent) via parent_is_alive. If the parent has exited, the service bails: continuing would leave an orphaned privileged process with no one to own the control channel or reap the result. The check is a liveness handshake between parent and child.
Source
Thrown at crates/astrid-storage-provider-winfsp/src/win.rs:197
&launch.lease.callback_path,
)
.map_err(anyhow::Error::msg)?;
let runtime = Arc::new(
tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()
.context("start WinFsp service runtime")?,
);
runtime.block_on(run_private_service(launch, challenge, runtime.clone()))
}
async fn run_private_service(
launch: StorageProviderServiceLaunchV1,
challenge: String,
runtime: Arc<tokio::runtime::Runtime>,
) -> Result<()> {
if !parent_is_alive(&launch.parent) {
bail!("WinFsp service parent process is not alive");
}
probe_callback(&launch).await?;
let listener = local_transport::bind(&launch.control_path).with_context(|| {
format!(
"bind WinFsp service control {}",
launch.control_path.display()
)
})?;
let callback = CallbackFs::new(launch.lease.clone(), runtime)
.map_err(|failure| anyhow::anyhow!("build WinFsp callback filesystem: {failure:?}"))?;
initialize_winfsp()?;
let mountpoint = U16CString::from_os_str(launch.mountpoint.as_os_str())
.map_err(|_| anyhow::anyhow!("WinFsp mountpoint is not valid UTF-16"))?;
let filesystem = FileSystem::start(
volume_params(launch.lease.access),
Some(&mountpoint),
callback,
)View on GitHub (pinned to affd8760f4)
Solutions
- Ensure the parent stays alive for the whole child startup handshake (wait for the ready challenge before exiting)
- Log and retry the launch if the parent was terminated, regenerating the launch document with a fresh live PID
- Verify parent_is_alive's inputs: the PID/token in the launch must refer to the actual launching process
- If the parent intentionally spawns and exits, restructure to keep a supervisor process alive instead
Example fix
// before spawn_service(&launch)?; std::process::exit(0); // parent gone before child validates liveness // after spawn_service(&launch)?; wait_for_service_ready(&launch); // parent stays alive through the handshake
Defensive patterns
Strategy: try-catch
Validate before calling
// parent side: confirm your own process is alive and the PID recorded is current assert_eq!(launch.parent.pid, std::process::id(), "launch must record the live parent PID");
Type guard
fn launch_parent_is_self(launch: &StorageProviderServiceLaunchV1) -> bool {
launch.parent.pid == std::process::id()
} Try / catch
match service_err {
Err(e) if e.to_string().contains("parent process is not alive") => {
eprintln!("parent exited during handshake; relaunch with a live supervisor");
relaunch_with_supervisor()?;
}
other => other?,
} Prevention
- Keep a supervisor process alive through the whole child handshake
- Never exit the parent before the service signals readiness
- Regenerate launch documents per run; never reuse stale ones
- Log parent PID at spawn to catch PID-reuse confusion
When it happens
Trigger: The parent process crashes or exits between writing the launch document and the service reading it; the launch embeds a stale parent PID/token from a previous run; the wrong PID was serialized into launch.parent.
Common situations: Parent killed by a timeout runner or Ctrl+C during startup; services launched by a short-lived bootstrap script that exits immediately; PID reuse pointing at a different (dead) process; relaunching a stale launch file.
Related errors
- WinFsp daemon lease exceeds limit
- WinFsp service launch exceeds limit
- WinFsp service parent PID is invalid
- WinFsp service parent start identity is invalid
- WinFsp stop timed out
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/4b36ef072a34e253.
Report an issue: GitHub.