astrid-runtime/astrid · critical · anyhow::Error

native local uplink listener is unavailable

Error message

native local uplink listener is unavailable

What it means

The daemon claims the kernel's native local uplink listener via `kernel.claim_native_uplink_listener()`; the API returns Option and None means the baseline control-plane socket could not be provided. Because Astrid owns its baseline control plane and must start it before loading any distribution capsules, a missing listener is fatal.

Solutions

  1. Check for and stop another running astrid daemon instance holding the listener.
  2. Verify the platform supports the local listener (unix socket availability) and no sandbox blocks socket creation.
  3. Restart the daemon; if None persists on a clean environment, report it as an internal invariant violation with logs.
Defensive patterns

Strategy: try-catch

Try / catch

// rust
match daemon::run(args).await {
    Err(e) if e.to_string().contains("uplink listener") => {
        eprintln!("another daemon may hold the uplink listener: {e:#}");
        std::process::exit(1);
    }
    Err(e) => { eprintln!("{e:#}"); std::process::exit(1); }
    Ok(()) => {}
}

Prevention

When it happens

Trigger: Calling daemon `run()` when `claim_native_uplink_listener()` returns None — typically the kernel failed to create/bind the canonical local listener (socket setup failure, resource exhaustion, or it was already claimed).

Common situations: Another astrid process already bound the canonical listener; OS-level socket limits or sandbox restrictions preventing listener creation on the platform.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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

Appendix: source

Thrown at crates/astrid-daemon/src/lib.rs:298

    if defer_logging {
        init_logging(&log_config);
    }
    kernel
        .set_system_capsules(
            unified_cfg
                .as_ref()
                .into_iter()
                .flat_map(|config| config.uplinks.iter())
                .map(|uplink| uplink.plugin.clone()),
        )
        .await;

    // Astrid owns its baseline control plane. Start it before loading optional
    // distribution capsules so no capsule can race the canonical listener or
    // make a clean runtime unbootable by being absent or broken.
    let native_listener = kernel
        .claim_native_uplink_listener()
        .ok_or_else(|| anyhow::anyhow!("native local uplink listener is unavailable"))?;
    let native_uplink_task = astrid_uplink::native::NativeUplink {
        listener: native_listener,
        session_token: std::sync::Arc::clone(&kernel.session_token),
        home: astrid_home.clone(),
        event_bus: std::sync::Arc::clone(&kernel.event_bus),
        shutdown: kernel.shutdown_tx.subscribe(),
    }
    .spawn();

    // In ephemeral mode, shut down immediately when the last client disconnects.
    if args.ephemeral {
        kernel.set_ephemeral(true);
    }

    // Load the boot-critical default view. Non-default profile principals warm
    // after readiness so a large tenant set cannot make daemon restart health
    // wait on every agent's capsule view.
    kernel.load_boot_capsules().await;

View on GitHub (pinned to affd8760f4)