astrid-runtime/astrid · error · GatewayError::Internal
daemon kernel-request: {e}
Error message
daemon kernel-request: {e} What it means
`daemon_kernel_error` is the shared mapper from `KernelClientError` to `GatewayError` used by gateway route handlers. If the kernel client error is a timeout it becomes `GatewayError::Timeout`, otherwise the whole error is wrapped as `GatewayError::Internal` with `daemon kernel-request: {e}`. It indicates the request to the daemon/kernel failed outside of normal application-level error responses.
Source
Thrown at crates/astrid-gateway/src/routes/mod.rs:62
/// Map a bus-direct / socket kernel-request failure ([`KernelClientError`]) to a
/// [`GatewayError`]. Single-sourced so every `kernel_client_for(...).request()`
/// call site maps consistently.
///
/// A [`Timeout`](KernelClientError::Timeout) — the daemon was slow / wedged, not
/// a transport fault — maps to **504** so callers can distinguish "still
/// processing, retry" (e.g. a heavy `InstallCapsule` under load) from a genuine
/// 500. Connection loss, bus shutdown, build, and decode failures all map to
/// **500**. A kernel-side rejection is a `KernelResponse::Error` handled at the
/// call site (→ 403), never reaching this path.
#[allow(
clippy::needless_pass_by_value,
reason = "consumed by Display formatting"
)]
pub(crate) fn daemon_kernel_error(e: KernelClientError) -> GatewayError {
if e.is_timeout() {
return GatewayError::Timeout(format!("daemon kernel-request: {e}"));
}
GatewayError::Internal(anyhow::anyhow!("daemon kernel-request: {e}"))
}
pub mod agent;
pub mod audit;
pub mod auth;
pub mod caps;
#[cfg(test)]
mod capsule_sources;
pub mod capsules;
pub mod distribution;
pub mod env;
pub mod events;
pub mod groups;
pub mod invites;
pub mod models;
pub mod observability;
pub mod principals;
pub mod quotas;View on GitHub (pinned to affd8760f4)
Solutions
- Confirm the daemon/kernel process is up and the configured endpoint matches (socket path/URL).
- Read the inner `{e}` in logs to classify: connection vs channel-closed vs serialization.
- Align gateway and daemon versions; redeploy together after protocol changes.
- For timeouts specifically, tune the kernel request timeout budget and check daemon load.
Example fix
// before
GatewayError::Internal(anyhow::anyhow!("daemon kernel-request: {e}"))
// after
if e.is_connect() {
return Err(GatewayError::ServiceUnavailable(format!("daemon unreachable: {e}")));
}
GatewayError::Internal(anyhow::anyhow!("daemon kernel-request: {e}")) Defensive patterns
Strategy: retry
Validate before calling
// before issuing the request
if !daemon_health_probe().await {
return Err(ServiceUnavailable("kernel daemon not ready"));
} Type guard
fn is_kernel_transport_failure(e: &KernelClientError) -> bool {
!e.is_timeout() && (e.is_connect() || e.is_channel_closed())
} Try / catch
match route_call(state, req).await {
Err(e) if is_kernel_transport_failure(&e) => {
// one bounded retry after backoff
tokio::time::sleep(RETRY_DELAY).await;
route_call(state, req).await
}
r => r,
} Prevention
- Start the daemon before the gateway or add startup readiness gating.
- Use a bounded retry with backoff for transient kernel errors.
- Validate the kernel endpoint configuration at boot and fail fast if unreachable.
- Classify KernelClientError variants into distinct GatewayError types (timeout/unavailable/internal).
When it happens
Trigger: Any gateway route using this mapper when the kernel client call fails with a non-timeout `KernelClientError`: connection refused, channel closed, serialization failure, or daemon-side transport fault.
Common situations: Daemon not started before the gateway; kernel socket path misconfigured in env/config; daemon crashed mid-request; version mismatch of the kernel IPC protocol after upgrading one side only.
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
- unexpected response from kernel: {other:?}
- daemon metadata lookup failed: {error}
- unexpected daemon metadata response: {other:?}
- daemon rejected capsule metadata request: {message}
- unexpected daemon response: {other:?}
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/73708c02c3efbe96.
Report an issue: GitHub.