astrid-runtime/astrid · error
an already-bound plain-HTTP listener cannot serve native TLS
Error message
an already-bound plain-HTTP listener cannot serve native TLS
What it means
Fires in run_with_capability_probe_on_listener: the caller handed in an already-bound plain TCP listener while GatewayState has a TLS config; TLS termination needs its own accept loop, so serving native TLS over that listener is refused rather than serving plaintext while believing it's TLS.
Solutions
- Bind the gateway through the TLS-aware startup path when config.tls is set
- Clear the tls config block if plaintext HTTP on this listener is actually intended
- Terminate TLS in a fronting proxy and run the gateway plain
Defensive patterns
Strategy: fallback
When it happens
Trigger: Thrown at crates/astrid-gateway/src/lib.rs:183 when the library encounters an invalid state.
Common situations: See trigger scenarios.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/0a0fbf2b2871559a.
Report an issue: GitHub.
Appendix: source
Thrown at crates/astrid-gateway/src/lib.rs:183
}
/// Run the gateway on an already-bound plain-HTTP listener.
///
/// # Errors
/// Returns an error when native TLS is configured, the listener address is
/// unavailable, or the HTTP server fails.
#[doc(hidden)]
pub async fn run_with_capability_probe_on_listener<F>(
state: Arc<GatewayState>,
listener: TcpListener,
shutdown: impl Future<Output = ()> + Send + 'static,
capability_probe: F,
) -> Result<()>
where
F: Fn(&astrid_core::PrincipalId, Option<&str>, &str) -> bool + Send + Sync + 'static,
{
if state.config.tls.is_some() {
anyhow::bail!("an already-bound plain-HTTP listener cannot serve native TLS");
}
let addr = listener
.local_addr()
.context("failed to read pre-bound gateway listener address")?;
warn_if_plaintext_non_loopback(addr);
state.hydrate_revocations().await?;
let workspace_root = std::env::current_dir().unwrap_or_else(|_| std::path::PathBuf::from("."));
serve_http_listener(
state,
listener,
shutdown,
workspace_root,
astrid_core::dirs::WorkspaceLayout::default(),
routes::events::CapabilityProbe::new(capability_probe),
)
.await
}
View on GitHub (pinned to affd8760f4)