netbirdio/netbird · error

split host port: %w

Error message

split host port: %w

What it means

Returned by Client.ListenTCP when net.SplitHostPort cannot parse the address argument. The listen address must include a port: a bare host ("svc"), a bare port ("8080" without colon), or an IPv6 literal with multiple unbracketed colons all fail here. Note the host part is discarded anyway: the client always binds its own overlay IP, so only the port matters.

Source

Thrown at client/embed/embed.go:378

	return nsnet.DialContext(ctx, network, address)
}

// DialContext dials a network address in the netbird network with context
func (c *Client) DialContext(ctx context.Context, network, address string) (net.Conn, error) {
	return c.Dial(ctx, network, address)
}

// ListenTCP listens on the given address in the netbird network.
// Not applicable if the userspace networking mode is disabled.
func (c *Client) ListenTCP(address string) (net.Listener, error) {
	nsnet, addr, err := c.getNet()
	if err != nil {
		return nil, err
	}

	_, port, err := net.SplitHostPort(address)
	if err != nil {
		return nil, fmt.Errorf("split host port: %w", err)
	}
	listenAddr := net.JoinHostPort(addr.String(), port)

	tcpAddr, err := net.ResolveTCPAddr("tcp", listenAddr)
	if err != nil {
		return nil, fmt.Errorf("resolve: %w", err)
	}
	return nsnet.ListenTCP(tcpAddr)
}

// ListenUDP listens on the given address in the netbird network.
// Not applicable if the userspace networking mode is disabled.
func (c *Client) ListenUDP(address string) (net.PacketConn, error) {
	nsnet, addr, err := c.getNet()
	if err != nil {
		return nil, err
	}

View on GitHub (pinned to 93e97f4bf1)

Solutions

  1. Always pass host:port or the convenient ":port" form: ListenTCP(":8080").
  2. Normalize user input with net.SplitHostPort (or net.JoinHostPort when building) before calling ListenTCP.
  3. Bracket IPv6 literals: "[fd00::1]:8080".

Example fix

// before
ln, err := client.ListenTCP("8080")

// after
ln, err := client.ListenTCP(":8080")
Defensive patterns

Strategy: validation

Validate before calling

if _, _, err := net.SplitHostPort(address); err != nil {
    address = ":" + strings.TrimPrefix(address, ":") // or reject: require host:port
    // simplest robust fix: address = net.JoinHostPort("", portStr)
}

Prevention

When it happens

Trigger: ListenTCP("8080"), ListenTCP("localhost") (no port), or ListenTCP("fd00::1:8080") without brackets around the IPv6 part.

Common situations: Passing a port-only integer as a string assuming it is accepted; forwarding a user-entered address that omitted the port; IPv6 addresses from config not normalized to bracket form.

Related errors


AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16). Data as JSON: /api/errors/8c116d7f18984e04. Report an issue: GitHub.