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

  1. Run `astrid restart` to identity-gatedly kill and respawn the daemon.
  2. Re-run `astrid status` once after a short wait — a booting daemon may just need to finish binding the socket.
  3. Check socket file permissions/ownership in the Astrid runtime dir.
  4. 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

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


AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09). Data as JSON: /api/errors/c51461f1c2aadb34. Report an issue: GitHub.