pbakaus/impeccable · critical
Error: no free port
Error message
Error: no free port
What it means
Without an explicit `--port`, the live server auto-scans upward from port 8400, incrementing on each failed bind. If every port through u16::MAX is exhausted, it prints this message and exits 1. It indicates the fallback port allocator could not find any bindable port — in practice this signals blocked binds rather than genuine port exhaustion.
Source
Thrown at crates/live/src/live_server.rs:292
match TcpListener::bind(("127.0.0.1", port)) {
Ok(l) => l,
Err(e) => {
io.err(&format!(
"Error: listen EADDRINUSE: address already in use 127.0.0.1:{} ({})\n",
port, e
));
return 1;
}
}
}
None => {
let mut port: u16 = 8400;
loop {
match TcpListener::bind(("127.0.0.1", port)) {
Ok(l) => break l,
Err(_) => {
if port == u16::MAX {
io.err("Error: no free port\n");
return 1;
}
port += 1;
}
}
}
}
};
let port = listener.local_addr().map(|a| a.port()).unwrap_or(0) as i64;
// Annotation session dir
let annot_root = live_annotations_dir(&cwd, &env);
let _ = std::fs::create_dir_all(&annot_root);
let session_dir = mkdtemp(&jsp::join(&[&annot_root, "session-"]));
{
let mut st = lock(&shared);
st.port = port;View on GitHub (pinned to 2bc2879276)
Solutions
- Check whether binds are blocked at the OS level (sandbox/seccomp/SELinux) — run the same start outside the sandbox.
- Inspect system listener count (`ss -ltn | wc -l`); close lingering listeners or restart the network namespace if thousands of sockets are stuck.
- Grant the container/user permission to bind loopback ports, or run the live server on the host.
Example fix
// before $ impeccable live-server Error: no free port // after $ ss -ltn | wc -l # inspect listener count $ impeccable live-server # run where loopback bind is permitted
Defensive patterns
Strategy: fallback
Validate before calling
// sanity-check that loopback binds are permitted at all before starting
python3 -c "import socket; s=socket.socket(); s.bind(('127.0.0.1',0)); s.close()" || { echo 'loopback bind blocked'; exit 2; } Try / catch
// treat 'no free port' as an environment failure, not a retry loop
try {
execSync('impeccable live-server');
} catch (e) {
if (/no free port/.test(String(e.stderr))) {
throw new Error('loopback binds blocked or exhausted in this environment; fix sandbox/OS policy, then retry');
}
throw e;
} Prevention
- Run the live server in an environment that permits loopback binds (check seccomp/SELinux/sandbox policies).
- Monitor system listener counts; avoid leaking thousands of sockets.
- If the scan exhausts, investigate the OS first — thousands of occupied ports nearly always indicate policy or leakage, not genuine demand.
When it happens
Trigger: Starting `live-server` without `--port` where the loop `TcpListener::bind(("127.0.0.1", port))` fails for every port from 8400 through 65535, hitting the `port == u16::MAX` guard.
Common situations: A sandbox or security policy (seccomp/SELinux) rejecting every loopback bind, which the scan misreads as 'port in use'; a system leaking thousands of stuck listeners; restricted containers where socket bind is disallowed entirely.
Related errors
- Error: listen EADDRINUSE: address already in use 127.0.0.1:{
- Status failed: ${res.status} ${res.statusText}
- Poll failed: ${res.status} ${res.statusText}
- TypeError: fetch failed: {}
- serve-question: server failed to start{}
AI-assisted analysis of pbakaus/impeccable@2bc2879276 (2026-09-08).
Data as JSON: /api/errors/3c6376bab725c4a2.
Report an issue: GitHub.