ruvnet/RuView · error
cannot bind UDP socket on {udp_addr}: {e}
Error message
cannot bind UDP socket on {udp_addr}: {e} What it means
tokio UdpSocket::bind failed for the CSI ingest address {udp_bind}:{udp_port} at calibrate-serve startup. The io::Error is typically AddrInUse (another process already bound that UDP port, e.g. a previous calibrate-serve, enroll, or room-watch instance), permission denied for privileged ports below 1024, or an invalid/unassignable --udp-bind address.
Source
Thrown at v2/crates/wifi-densepose-cli/src/calibrate_api.rs:320
.route("/api/v1/calibration/baselines", get(baselines))
.route("/api/v1/room/state", get(room_state))
.route("/api/v1/room/train", post(train_room))
.route("/api/v1/enroll/anchor", post(enroll_anchor))
.route("/api/v1/enroll/geometry", post(enroll_geometry))
.route("/api/v1/enroll/status", get(enroll_status))
.layer(CorsLayer::permissive())
.with_state(state)
}
/// Run the calibration HTTP API server (blocks until Ctrl-C).
pub async fn execute(args: CalibrateServeArgs) -> Result<()> {
std::fs::create_dir_all(&args.output_dir)
.map_err(|e| anyhow::anyhow!("cannot create output dir {}: {e}", args.output_dir))?;
let udp_addr = format!("{}:{}", args.udp_bind, args.udp_port);
let socket = UdpSocket::bind(&udp_addr)
.await
.map_err(|e| anyhow::anyhow!("cannot bind UDP socket on {udp_addr}: {e}"))?;
eprintln!("[calibrate-serve] CSI ingest on udp://{udp_addr}");
let status = Arc::new(RwLock::new(SharedStatus {
udp_port: args.udp_port,
default_tier: args.tier.clone(),
output_dir: args.output_dir.clone(),
..Default::default()
}));
let (cmd_tx, cmd_rx) = mpsc::channel::<CalCommand>(8);
let window = Arc::new(RwLock::new(VecDeque::<f32>::with_capacity(LIVE_WINDOW)));
let enroll = Arc::new(RwLock::new(HashMap::<String, RoomEnroll>::new()));
// Background ingest task owns the socket + recorder.
{
let status = status.clone();
let default_tier = args.tier.clone();
let output_dir = args.output_dir.clone();View on GitHub (pinned to 4685618388)
Solutions
- Free the port: stop the other process (ss -ulpn / lsof -i udp/<port>) or pick a different --udp-port
- Use a UDP port of 1024 or higher, or grant the capability when a low port is required
- Pass a numeric, bindable address in --udp-bind (127.0.0.1, 0.0.0.0, or a NIC IP)
- After changing the port, align the ESP32 firmware's CSI destination port with it
Example fix
// before $ ruview calibrate-serve --udp-port 9999 # cannot bind: AddrInUse (old instance) // after $ ss -ulpn | grep 9999 $ kill <old-pid> $ ruview calibrate-serve --udp-port 9999
Defensive patterns
Strategy: validation
Validate before calling
fn udp_port_free(bind: &str, port: u16) -> bool {
std::net::UdpSocket::bind((bind, port)).is_ok()
} Try / catch
match UdpSocket::bind(&udp_addr).await {
Ok(socket) => socket,
Err(e) if e.kind() == std::io::ErrorKind::AddrInUse => {
return Err(anyhow::anyhow!("udp://{udp_addr} already in use — stop the other CSI tool or change --udp-port"));
}
Err(e) => return Err(anyhow::anyhow!("cannot bind UDP socket on {udp_addr}: {e}")),
} Prevention
- Run one CSI ingest service per UDP port per host; use a process manager that stops old instances first
- Prefer unprivileged high ports for CSI ingest
- Bind 127.0.0.1 unless remote nodes must stream in, and pair non-loopback HTTP binds with --token
When it happens
Trigger: Starting calibrate-serve while another calibrate-serve/enroll/room-watch still holds the same UDP port; --udp-port below 1024 as non-root; passing a --udp-bind literal that cannot be parsed or is not assigned to the host.
Common situations: A previous server instance was never stopped (orphaned process, missing systemd stop); two CSI tools configured to the same default port; containers without CAP_NET_BIND_SERVICE trying low ports.
Related errors
- cannot bind {addr}: {e}
- cannot bind UDP socket on {addr}: {e}
- cannot bind HTTP listener on {http_addr}: {e}
- calibration failed: {e}
- cannot write {output}: {e}
AI-assisted analysis of ruvnet/RuView@4685618388 (2026-08-16).
Data as JSON: /api/errors/69be4a2b710eb0a8.
Report an issue: GitHub.