slackhq/nebula · error

only wildcard address supported, got %q %v

Error message

only wildcard address supported, got %q %v

What it means

Service.Listen only accepts the wildcard IPv4 address 0.0.0.0 (or an unset IP). After net.ResolveTCPAddr succeeds, Listen rejects any resolved IP that is not all-zero bytes. It exists because the in-memory netstack listener binds per-port on the stack rather than per-specific-address.

Source

Thrown at service/service.go:219

}

// Dial dials the provided address
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()

View on GitHub (pinned to dd8f660c0a)

Solutions

  1. Pass "tcp" plus a wildcard address such as ":8080" or "0.0.0.0:8080".
  2. Strip the host from your address before calling Listen, keeping only the port.
  3. Use Listen("tcp", ":%d") with a numeric port instead of a resolved hostname.

Example fix

// before
l, err := svc.Listen("tcp", "127.0.0.1:8080")
// after
l, err := svc.Listen("tcp", ":8080")
Defensive patterns

Strategy: validation

Validate before calling

a, err := net.ResolveTCPAddr(network, address)
if err != nil {
    return err
}
if a.IP != nil && !a.IP.Equal(net.IPv4zero) {
    return fmt.Errorf("this listener only supports wildcard bind, got %s", a.IP)
}

Type guard

func isWildcardTCPAddr(a *net.TCPAddr) bool {
    return a.IP == nil || a.IP.Equal(net.IPv4zero)
}

Try / catch

l, err := svc.Listen(network, address)
if err != nil {
    if strings.Contains(err.Error(), "only wildcard address supported") {
        address = fmt.Sprintf(":%d", portOnly(address))
        l, err = svc.Listen(network, address)
    }
    if err != nil {
        return err
    }
}

Prevention

When it happens

Trigger: Calling Service.Listen("tcp", "127.0.0.1:8080") or "192.168.1.5:8080" or an IPv6 wildcard "[::]:8080"; any non-nil addr.IP not equal to []byte{0,0,0,0} trips the check at service/service.go:219.

Common situations: Binding to localhost (127.0.0.1) as a habit from real servers; resolving a hostname that yields a concrete IP; passing ":8080" through a helper that prepends a host; IPv6 wildcard "::" which is 16 zero bytes and fails the 4-byte comparison.

Related errors


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