astrid-runtime/astrid · error
an Astrid daemon appears to be running but its uplink is unr
Error message
an Astrid daemon appears to be running but its uplink is unreachable; run `astrid restart`
What it means
After deciding the daemon might be live, `astrid status` attempts a socket connection to the kernel under STATUS_CONNECT_TIMEOUT. If connecting or the timeout fails while a recorded daemon PID is still alive, the CLI bails: the daemon process exists but its uplink (the Unix socket) is not serviceable. Like the pre-connect variant, the fix is `astrid restart`, since start will not force-recycle a live PID.
Source
Thrown at crates/astrid-cli/src/commands/daemon.rs:595
print_status(output_format, None)?;
return Ok(());
},
StatusAction::RunningButUnreachable => {
anyhow::bail!(
"an Astrid daemon appears to be running but its uplink is unreachable (missing or unlinked system.sock while the PID/lock is live). run `astrid restart`"
);
},
StatusAction::QueryLiveSocket => {},
}
let connect = tokio::time::timeout(
STATUS_CONNECT_TIMEOUT,
socket_client::connect_kernel_for_workspace(None),
)
.await;
let Ok(Ok(mut client)) = connect else {
if recorded_alive {
anyhow::bail!(
"an Astrid daemon appears to be running but its uplink is unreachable; run `astrid restart`"
);
}
print_status(output_format, None)?;
return Ok(());
};
let status = status_response(
client
.request(KernelRequest::GetStatus)
.await
.context("Failed to query daemon status")?,
)?;
print_status(output_format, Some(&status))?;
Ok(())
}
fn print_status(output_format: OutputFormat, status: Option<&DaemonStatus>) -> Result<()> {
if output_format == OutputFormat::Json {View on GitHub (pinned to affd8760f4)
Solutions
- Run `astrid restart` to identity-gatedly kill and respawn the daemon.
- Re-run `astrid status` once after a short wait — a booting daemon may just need to finish binding the socket.
- Check socket file permissions/ownership in the Astrid runtime dir.
- If it recurs, inspect daemon logs for a wedged event loop or listener crash.
Example fix
// before $ astrid status Error: an Astrid daemon appears to be running but its uplink is unreachable; run `astrid restart` // after $ astrid restart && astrid status
Defensive patterns
Strategy: retry
Validate before calling
// pre-check: is the socket connectable before invoking status?
let connect = tokio::time::timeout(STATUS_CONNECT_TIMEOUT, socket_client::connect_kernel_for_workspace(None)).await;
if connect.is_err() && recorded_daemon_pid_is_alive() {
run(vec!["astrid", "restart"])?; // heal before asking for status
} Type guard
fn is_unreachable_uplink(err: &anyhow::Error) -> bool {
err.to_string().contains("uplink is unreachable")
} Try / catch
match astrid_status().await {
Ok(s) => s,
Err(e) if is_unreachable_uplink(&e) => {
run(vec!["astrid", "restart"]).await?;
astrid_status().await?
}
Err(e) => return Err(e),
} Prevention
- Allow STATUS_CONNECT_TIMEOUT headroom on slow/loaded machines so a booting daemon isn't misread as unreachable.
- After CLI upgrades, always restart the daemon to avoid protocol/behavior drift.
- Check socket file permissions and LSM (SELinux/AppArmor) denials when this recurs.
- Use `astrid status` after `restart` to confirm the new daemon bound its socket.
When it happens
Trigger: `astrid status` where socket exists enough to attempt a connect, but connect_kernel_for_workspace(None) errors or exceeds STATUS_CONNECT_TIMEOUT, and recorded_daemon_pid_is_alive() is true.
Common situations: Daemon hung (event loop blocked) so it accepts nothing; socket file present but listener closed; permission mismatch on the socket file; boot-time race where the daemon hasn't bound the socket yet within the timeout; SELinux/AppArmor blocking local socket connects.
Understand the failure class
Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.
Related errors
- daemon rejected capsule metadata request: {message}
- daemon rejected capsule metadata request: {message}
- an Astrid daemon appears to be running but its uplink is unr
- Admin request timed out after {:?} waiting for {want_respons
- connection timed out after 5s
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/c51461f1c2aadb34.
Report an issue: GitHub.