abiosoft/colima · critical

error closing temporary port listener: %w

Error message

error closing temporary port listener: %w

What it means

RandomAvailablePort (util/util.go:33) closes its just-created throwaway listener and calls logrus.Fatal if Close returns an error, exiting the process. A close of a freshly bound listener essentially cannot fail unless the fd was already closed elsewhere (double close) or the kernel/network stack is in a faulted state. In practice this line is unreachable defensive code around fd lifecycle bugs.

Source

Thrown at util/util.go:33

// HomeDir returns the user home directory.
func HomeDir() string {
	home, err := os.UserHomeDir()
	if err != nil {
		// this should never happen
		logrus.Fatal(fmt.Errorf("error retrieving home directory: %w", err))
	}
	return home
}

// RandomAvailablePort returns an available port on the host machine.
func RandomAvailablePort() int {
	listener, err := net.Listen("tcp", ":0")
	if err != nil {
		logrus.Fatal(fmt.Errorf("error picking an available port: %w", err))
	}

	if err := listener.Close(); err != nil {
		logrus.Fatal(fmt.Errorf("error closing temporary port listener: %w", err))
	}

	return listener.Addr().(*net.TCPAddr).Port
}

// isPortAvailable checks if a specific port is available on the host.
func isPortAvailable(port int) bool {
	listener, err := net.Listen("tcp", fmt.Sprintf(":%d", port))
	if err != nil {
		return false
	}
	if err := listener.Close(); err != nil {
		return false
	}
	return true
}

// FindAvailablePort finds the first available port starting from startPort.

View on GitHub (pinned to c3a5f9184d)

Solutions

  1. Rerun the command — a transient kernel state clears on retry
  2. If it reproduces, audit code paths that took ownership of the listener for double-close bugs
  3. Check `lsof | wc -l` against `ulimit -n` to rule out fd-table pressure
  4. As a last resort reboot to reset the network stack state

Example fix

// before (fork bug: listener closed twice)
port := listener.Addr().(*net.TCPAddr).Port
listener.Close()
return port, listener // caller closes again -> fatal

// after
port := listener.Addr().(*net.TCPAddr).Port
listener.Close()
return port, nil
Defensive patterns

Strategy: retry

Try / catch

// Close errors on a throwaway listener are transient; ignore-and-continue
// is safe because the port number was already captured:
port := listener.Addr().(*net.TCPAddr).Port
if err := listener.Close(); err != nil {
    log.Debugf("ignoring temp-listener close error: %v", err)
}

Prevention

When it happens

Trigger: A double-close of the listener fd (a code bug, not a runtime condition), or pathological kernel/network-stack states where even close(2) errors; observable as an immediate FATAL during port setup.

Common situations: Almost none in stock colima; would surface in forks that refactor RandomAvailablePort and lose/re-close the listener; severe system-level fd table corruption after resource exhaustion.

Related errors


AI-assisted analysis of abiosoft/colima@c3a5f9184d (2026-08-15). Data as JSON: /api/errors/4f3ff450377296f9. Report an issue: GitHub.