cli/cli · error
failed to listen to local port over tcp: %w
Error message
failed to listen to local port over tcp: %w
What it means
Thrown by ListenTCP when net.ListenTCP cannot bind the TCP listener at 127.0.0.1:port (or 0.0.0.0 when allInterfaces is true). This is the classic bind failure: the port is already in use, the port is privileged (<1024) for a non-root user, or the address is otherwise unavailable.
Source
Thrown at internal/codespaces/codespaces.go:144
}
return codespace, nil
}
// ListenTCP starts a localhost tcp listener on 127.0.0.1 (unless allInterfaces is true) and returns the listener and bound port
func ListenTCP(port int, allInterfaces bool) (*net.TCPListener, int, error) {
host := "127.0.0.1"
if allInterfaces {
host = ""
}
addr, err := net.ResolveTCPAddr("tcp", fmt.Sprintf("%s:%d", host, port))
if err != nil {
return nil, 0, fmt.Errorf("failed to build tcp address: %w", err)
}
listener, err := net.ListenTCP("tcp", addr)
if err != nil {
return nil, 0, fmt.Errorf("failed to listen to local port over tcp: %w", err)
}
port = listener.Addr().(*net.TCPAddr).Port
return listener, port, nil
}
View on GitHub (pinned to 0eeec0b92e)
Solutions
- Free the port: find the process with lsof -i :PORT (macOS/Linux) or netstat -ano | findstr PORT (Windows) and stop it.
- Use a different local port, or pass port 0 to let the OS pick a free one (the actual bound port is returned).
- For privileged ports, choose >=1024 unless running with appropriate capabilities.
- Kill stale gh processes from earlier sessions (ps aux | grep gh).
Example fix
// before
listener, port, err := codespaces.ListenTCP(3000, false)
// after
listener, port, err := codespaces.ListenTCP(0, false) // OS picks a free port
fmt.Println("forwarding on local port:", port) Defensive patterns
Strategy: validation
Validate before calling
func portAvailable(port int) bool {
ln, err := net.Listen("tcp", fmt.Sprintf("127.0.0.1:%d", port))
if err != nil {
return false
}
ln.Close()
return true
}
if port != 0 && !portAvailable(port) {
return fmt.Errorf("local port %d already in use", port)
} Try / catch
listener, port, err := codespaces.ListenTCP(wantPort, allInterfaces)
if err != nil {
if strings.Contains(err.Error(), "failed to listen") {
listener, port, err = codespaces.ListenTCP(0, allInterfaces) // fall back to OS-assigned port
}
if err != nil {
return err
}
} Prevention
- Probe port availability before binding.
- Fall back to port 0 when the desired port is taken.
- Clean up listeners with defer listener.Close() to avoid leaking ports.
When it happens
Trigger: Local port forwarding for a codespace (gh codespace ports forward / ssh) where the local port is occupied by another process, a previous forwarding session did not release the port, or a privileged port was requested without privileges; with allInterfaces=true, binding 0.0.0.0 may be blocked by firewall policy.
Common situations: Running two forwardings of the same local port; a stale gh process holding the port; choosing ports <1024; port already taken by a dev server (3000, 8080, ...).
Related errors
- failed to listen to local port over tcp: %w
- failed to build tcp address: %w
- failed to build tcp address: %w
- failed to create port forwarder: %w
- failed to create port forwarder: %w
AI-assisted analysis of cli/cli@0eeec0b92e (2026-08-15).
Data as JSON: /api/errors/e38d9868ae4c9b7a.
Report an issue: GitHub.