astrid-runtime/astrid · warning
Windows named-pipe endpoint is busy
Error message
Windows named-pipe endpoint is busy
What it means
ERROR_PIPE_BUSY from CreateFile means the pipe exists but all its instances currently have a waiting client or are occupied — no free instance to serve a new connection. The library maps it to io::ErrorKind::WouldBlock, signaling a transient condition the caller should retry (possibly after the server calls CreateNamedPipe again for a new instance).
Solutions
- Retry the connect on WouldBlock with short backoff — this is the intended handling for ERROR_PIPE_BUSY.
- Increase server concurrency: accept promptly and recreate pipe instances, or use WaitNamedPipe to wait for a free instance before connecting.
- Reduce client concurrency or pool connections to the pipe.
Example fix
// before
let stream = transport.connect(&path)?;
// after
let stream = loop {
match transport.connect(&path) {
Ok(s) => break s,
Err(e) if e.kind() == io::ErrorKind::WouldBlock => { std::thread::sleep(BACKOFF); }
Err(e) => return Err(e),
}
}; Defensive patterns
Strategy: retry
Try / catch
match transport.connect(&path) {
Err(e) if e.kind() == io::ErrorKind::WouldBlock => {
// all instances busy: exponential backoff, optionally WaitNamedPipe first
std::thread::sleep(BACKOFF);
retry_connect(&path)
}
other => other,
} Prevention
- Keep the server accept loop fast so instances free up quickly.
- Create multiple pipe instances for high-concurrency IPC.
- Add client-side jittered backoff instead of tight reconnect loops.
When it happens
Trigger: Multiple clients connecting concurrently to a single-instance pipe server; server accept loop busy so no instance is listening; client already queued for one instance while opening another.
Common situations: High-concurrency IPC where the server created too few pipe instances; slow accept loop under load; thundering-herd client reconnects after a server restart.
Related errors
- named-pipe client disconnected before transport…
- named-pipe DACL contains a non-canonical access entry
- named-pipe DACL control is not explicit and protected
- named-pipe DACL grants an unexpected or duplicate principal
- named-pipe DACL has entries; expected exactly
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/8e2e8a616c3c2b44.
Report an issue: GitHub.
Appendix: source
Thrown at crates/astrid-core/src/local_transport/windows.rs:664
}
let error = io::Error::last_os_error();
match error.raw_os_error().map(i32::cast_unsigned) {
Some(ERROR_FILE_NOT_FOUND) => Ok(EndpointState::Absent),
Some(ERROR_PIPE_BUSY | ERROR_SEM_TIMEOUT | ERROR_ACCESS_DENIED) => {
Ok(EndpointState::BusyOrDenied)
},
_ => Err(error),
}
}
fn classify_connect_error(error: io::Error) -> io::Error {
match error.raw_os_error().map(i32::cast_unsigned) {
Some(ERROR_FILE_NOT_FOUND) => io::Error::new(
io::ErrorKind::NotFound,
"Windows named-pipe endpoint is absent",
),
Some(ERROR_PIPE_BUSY) => io::Error::new(
io::ErrorKind::WouldBlock,
"Windows named-pipe endpoint is busy",
),
Some(ERROR_ACCESS_DENIED) => io::Error::new(
io::ErrorKind::PermissionDenied,
"Windows named-pipe endpoint denied access",
),
_ => error,
}
}
struct PipeSecurity {
_descriptor: LocalAllocation,
attributes: SECURITY_ATTRIBUTES,
}
impl PipeSecurity {
fn for_current_user() -> io::Result<Self> {View on GitHub (pinned to affd8760f4)