block/buzz · critical · anyhow::Error
Failed to bind
Error message
Failed to bind {}: {e} What it means
This is the bind of buzz-relay's main WebSocket listener: TcpListener::bind(&config.bind_addr) in serve() (crates/buzz-relay/src/main.rs:1330). bind_addr comes from the relay config (BUZZ_BIND_ADDR, parsed by parse_bind_addr in config.rs). Any kernel bind failure is wrapped in anyhow with the full address and aborts startup.
Solutions
- Check who holds the address: `ss -ltnp 'sport = :<port>'` and stop the duplicate listener.
- Change BUZZ_BIND_ADDR to a free port/IP (e.g. 127.0.0.1:3000 for local dev) in .env.
- Verify the IP in BUZZ_BIND_ADDR exists: `ip addr` — if not, bind 0.0.0.0:<port> or fix the interface address.
- For privileged ports, grant CAP_NET_BIND_SERVICE or front the relay with a proxy that binds 443 for it.
- In docker-compose/K8s, make sure only one replica binds a host port when using host networking.
Example fix
# before BUZZ_BIND_ADDR=10.0.1.5:3000 # IP not present on this host # error: Failed to bind 10.0.1.5:3000: Cannot assign requested address # after BUZZ_BIND_ADDR=0.0.0.0:3000
Defensive patterns
Strategy: validation
Validate before calling
# verify address exists on this host and port is free before launch
ip -4 addr | grep -F "$BIND_IP" || { echo "BUZZ_BIND_ADDR IP not present" >&2; exit 1; }
ss -ltnH "sport = :$BIND_PORT" | grep -q . && { echo "port busy" >&2; exit 1; } || true Prevention
- Bind 0.0.0.0:<port> unless a specific interface is required; it removes EADDRNOTAVAIL class failures.
- Keep one relay per host/port; use container networking instead of host networking for parallel instances.
- Include the bind address in health/log output (relay logs 'buzz-relay TCP listening') and check it on boot.
- Automate port allocation in dev (e.g. per-worktree ports) so two worktrees never collide.
When it happens
Trigger: Binding the main relay socket fails when: (1) AddrInUse — another relay or any process already listens on that ip:port; (2) PermissionDenied — port < 1024 without privileges; (3) EADDRNOTAVAIL — BUZZ_BIND_ADDR names an IP that does not exist on this host (typical when copying a config from another machine or binding a docker-internal IP directly on the host); (4) EACCES on the port due to local firewall reserved-port ranges (ip_local_reserved_ports / SELinux).
Common situations: Two `just relay` sessions on one dev box; a previous relay still running inside Docker while you start one on the host; BUZZ_BIND_ADDR set to 10.x cluster IP on a laptop; switching a deployment from port 3000 to 443 without granting the capability.
Related errors
- Failed to bind health port
- mesh endpoint bind on
- observer control subscribe error
- Server error
- BUZZ_UDS_PATH exists but is not a socket
AI-assisted analysis of block/buzz@ef2aa1ae38 (2026-08-20).
Data as JSON: /api/errors/2e3633783dc422ce.
Report an issue: GitHub.
Appendix: source
Thrown at crates/buzz-relay/src/main.rs:1448
// retains ownership of every delayed close until its 1012 frame has
// been flushed and acknowledged (or its send loop cancelled).
let closed = if drain_jitter_ms == 0 {
drain_conn_manager.drain_all()
} else {
drain_conn_manager.drain_all_jittered(drain_jitter_ms).await
};
info!(
connections = closed,
jitter_ms = drain_jitter_ms,
max_jitter_ms = MAX_DRAIN_JITTER_MS,
"Signalled restart close to all live WebSocket connections"
);
hard_shutdown_abort
});
let tcp_listener = tokio::net::TcpListener::bind(&config.bind_addr)
.await
.map_err(|e| anyhow::anyhow!("Failed to bind {}: {e}", config.bind_addr))?;
info!(addr = %config.bind_addr, "buzz-relay TCP listening");
#[cfg(unix)]
if let Some(ref uds_path) = config.uds_path {
use std::os::unix::fs::FileTypeExt as _;
match std::fs::symlink_metadata(uds_path) {
Ok(meta) if meta.file_type().is_socket() => {
let _ = std::fs::remove_file(uds_path);
}
Ok(_) => {
return Err(anyhow::anyhow!(
"BUZZ_UDS_PATH {uds_path} exists but is not a socket"
));
}
Err(_) => {}
}
let uds_listener = tokio::net::UnixListener::bind(uds_path)
.map_err(|e| anyhow::anyhow!("Failed to bind UDS {uds_path}: {e}"))?;View on GitHub (pinned to ef2aa1ae38)