slackhq/nebula · error

specific port required, got 0

Error message

specific port required, got 0

What it means

Service.Listen requires the caller to pin an exact port; it resolves the address and rejects port 0 because the user-device listener cannot allocate an ephemeral port. The address must also be the IPv4 wildcard (0.0.0.0) with a specific nonzero port in the valid uint16 range.

Source

Thrown at service/service.go:222

func (s *Service) Dial(network, address string) (net.Conn, error) {
	return s.DialContext(context.Background(), network, address)
}

// Listen listens on the provided address. Currently only TCP with wildcard
// addresses are supported.
func (s *Service) Listen(network, address string) (net.Listener, error) {
	if network != "tcp" && network != "tcp4" {
		return nil, errors.New("only tcp is supported")
	}
	addr, err := net.ResolveTCPAddr(network, address)
	if err != nil {
		return nil, err
	}
	if addr.IP != nil && !bytes.Equal(addr.IP, []byte{0, 0, 0, 0}) {
		return nil, fmt.Errorf("only wildcard address supported, got %q %v", address, addr.IP)
	}
	if addr.Port == 0 {
		return nil, errors.New("specific port required, got 0")
	}
	if addr.Port < 0 || addr.Port >= math.MaxUint16 {
		return nil, fmt.Errorf("invalid port %d", addr.Port)
	}
	port := uint16(addr.Port)

	l := &tcpListener{
		port:   port,
		s:      s,
		addr:   addr,
		accept: make(chan net.Conn),
	}

	s.mu.Lock()
	defer s.mu.Unlock()

	if _, ok := s.mu.listeners[port]; ok {
		return nil, fmt.Errorf("already listening on port %d", port)

View on GitHub (pinned to dd8f660c0a)

Solutions

  1. Choose an explicit port, e.g. "0.0.0.0:4242".
  2. If a free port is needed, probe for one with net.Listen("tcp", "127.0.0.1:0") on a normal listener, capture the chosen port, close it, and pass that port to s.Listen (accepting the small race).
  3. Validate the port is 1–65535 before calling Listen.

Example fix

// before
ln, err := s.Listen("tcp", "0.0.0.0:0")
// after
ln, err := s.Listen("tcp", "0.0.0.0:8080")
Defensive patterns

Strategy: validation

Validate before calling

addr, err := net.ResolveTCPAddr("tcp4", address)
if err != nil {
    return err
}
if addr.Port == 0 {
    return errors.New("Service.Listen requires an explicit non-zero port")
}

Try / catch

ln, err := s.Listen("tcp", address)
if err != nil {
    if err.Error() == "specific port required, got 0" {
        return fmt.Errorf("pick an explicit port instead of :0 for %q", address)
    }
    return err
}

Prevention

When it happens

Trigger: Calling s.Listen("tcp", "0.0.0.0:0") (or any address where net.ResolveTCPAddr yields Port == 0) — commonly to let the OS pick a free port.

Common situations: Using :0 for ephemeral port allocation out of habit; omitting the port entirely in the address string (which resolves to 0); dynamically generated addresses with empty port fields.

Related errors


AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03). Data as JSON: /api/errors/efd0e43b1681ec95. Report an issue: GitHub.