tailscale/tailscale · error

tsnet: no available port in ephemeral range

Error message

tsnet: no available port in ephemeral range

What it means

registerListener tried to allocate an ephemeral port for a non-TUN listener that requested port 0, but every port in the 10002 to 19999 range is already registered for that network, address, and funnel combination. The process has exhausted its ephemeral listener range.

Source

Thrown at tsnet/tsnet.go:2143

	}
	ln, err := s.netstack.ListenTCP(nsNetwork, nsAddr.String())
	if err != nil {
		return nil, fmt.Errorf("tsnet: %w", err)
	}
	return ln, nil
}

// registerListener allocates a port (if 0) and registers the listener in
// s.listeners under s.mu.
func (s *Server) registerListener(network, addr string, host netip.AddrPort, lnOn listenOn, gonetLn net.Listener) (*listener, error) {
	s.mu.Lock()
	defer s.mu.Unlock()

	// Allocate an ephemeral port for non-TUN listeners requesting port 0.
	if host.Port() == 0 && gonetLn == nil {
		p, ok := s.allocEphemeralLocked(network, host.Addr(), lnOn)
		if !ok {
			return nil, errors.New("tsnet: no available port in ephemeral range")
		}
		host = netip.AddrPortFrom(host.Addr(), p)
		addr = listenAddr(host)
	}

	var keys []listenKey
	switch lnOn {
	case listenOnTailnet:
		keys = append(keys, listenKey{network, host.Addr(), host.Port(), false})
	case listenOnFunnel:
		keys = append(keys, listenKey{network, host.Addr(), host.Port(), true})
	case listenOnBoth:
		keys = append(keys, listenKey{network, host.Addr(), host.Port(), false})
		keys = append(keys, listenKey{network, host.Addr(), host.Port(), true})
	}

	for _, key := range keys {
		if _, ok := s.listeners[key]; ok {

View on GitHub (pinned to 57c3357fdb)

Solutions

  1. Close unused listeners to free ports in the ephemeral range
  2. Request an explicit port instead of 0
  3. Audit for a listener leak if this occurs under normal load
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at tsnet/tsnet.go:2106 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of tailscale/tailscale@57c3357fdb (2026-08-18). Data as JSON: /api/errors/cdd8c3f941770182. Report an issue: GitHub.