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
- Always pass host:port or the convenient ":port" form: ListenTCP(":8080").
- Normalize user input with net.SplitHostPort (or net.JoinHostPort when building) before calling ListenTCP.
- 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
- Standardize on the ":port" form for ListenTCP/ListenUDP since the host is replaced anyway.
- Build addresses with net.JoinHostPort, never string concatenation.
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.