astrid-runtime/astrid · error
named-pipe peer PID did not identify the opened process
Error message
named-pipe peer PID did not identify the opened process
What it means
peer_process_identity opens the peer PID with OpenProcess and then calls GetProcessId on the returned handle to confirm the handle really refers to that PID. If the handle resolves to a different PID (handle recycling / PID reuse or an API inconsistency), identity cannot be trusted and the library fails closed with PermissionDenied.
Source
Thrown at crates/astrid-core/src/local_transport/windows.rs:437
if peer_process_id(stream)? != self.process_id {
return Err(io::Error::new(
io::ErrorKind::PermissionDenied,
"named-pipe peer process changed during authentication",
));
}
Ok(())
}
}
fn peer_process_identity(stream: &LocalStream) -> io::Result<VerifiedPeerProcess> {
let process_id = peer_process_id(stream)?;
let process = unsafe { OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, 0, process_id) };
if process.is_null() {
return Err(last_error("failed to open named-pipe peer process"));
}
let process = OwnedHandle(process);
if unsafe { GetProcessId(process.0) } != process_id {
return Err(io::Error::new(
io::ErrorKind::PermissionDenied,
"named-pipe peer PID did not identify the opened process",
));
}
let mut token = ptr::null_mut();
let opened = unsafe { OpenProcessToken(process.0, TOKEN_QUERY, &raw mut token) };
if opened == 0 || token.is_null() {
return Err(last_error("failed to open named-pipe peer process token"));
}
let user_sid = token_user_sid(&OwnedHandle(token))?;
Ok(VerifiedPeerProcess {
process_id,
user_sid,
_process: process,
})
}
View on GitHub (pinned to affd8760f4)
Solutions
- Treat the peer as unverified: re-authenticate the connection (new handshake, new PID capture).
- Retry the connection promptly — PID reuse windows are usually transient.
- If this recurs, verify the client is not dying mid-handshake and that only one process is connecting per pipe instance.
Defensive patterns
Strategy: retry
Try / catch
match result {
Err(e) if e.to_string().contains("did not identify the opened process") => {
// transient PID/handle inconsistency: re-authenticate with backoff
retry_with_backoff(authenticate, 3)
}
other => other,
} Prevention
- Re-verify peer identity promptly after capturing the PID to shrink the reuse window.
- Keep client lifetimes stable during handshake; avoid heavy process churn during IPC setup.
- Fall back to full re-authentication rather than trusting a cached VerifiedPeerProcess.
When it happens
Trigger: Calling connect/accept (via peer_is_current_user or require_current_user_process_peer) when the PID captured from the pipe was recycled by the OS between capture and OpenProcess, or OpenProcess returned a mismatched handle.
Common situations: Long-lived servers re-verifying peers whose PIDs were reused after process churn; heavily loaded systems with rapid process creation/destruction.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- named-pipe peer process changed during authentication
- named-pipe peer process belongs to a different operating-sys
- named-pipe client's effective token belongs to a different o
- named-pipe endpoint path must not contain a parent component
- Windows named-pipe endpoint denied access
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/0183b8c51286185b.
Report an issue: GitHub.