netbirdio/netbird · error
invalid address %s
Error message
invalid address %s
What it means
SingleSocketUDPMux.GetConn(ufrag, addr, candidateID) keys muxed connections by ufrag but first validates addr: unless the mux was created over an unspecified address (detected via localAddrsForUnspecified being non-empty), the provided addr must string-equal the bound socket's LocalAddr. This error rejects a request for a connection with a different address than the single socket the mux owns.
Source
Thrown at client/iface/udpmux/mux.go:251
m.mu.Lock()
defer m.mu.Unlock()
if len(m.localAddrsForUnspecified) > 0 {
return slices.Clone(m.localAddrsForUnspecified)
}
return []net.Addr{m.LocalAddr()}
}
// GetConn returns a PacketConn given the connection's ufrag and network address
// creates the connection if an existing one can't be found
func (m *SingleSocketUDPMux) GetConn(ufrag string, addr net.Addr, candidateID string) (net.PacketConn, error) {
// don't check addr for mux using unspecified address
m.mu.Lock()
lenLocalAddrs := len(m.localAddrsForUnspecified)
m.mu.Unlock()
if lenLocalAddrs == 0 && m.params.UDPConn.LocalAddr().String() != addr.String() {
return nil, fmt.Errorf("invalid address %s", addr.String())
}
var isIPv6 bool
if udpAddr, _ := addr.(*net.UDPAddr); udpAddr != nil && udpAddr.IP.To4() == nil {
isIPv6 = true
}
m.mu.Lock()
defer m.mu.Unlock()
if m.IsClosed() {
return nil, io.ErrClosedPipe
}
if conn, ok := m.getConn(ufrag, isIPv6); ok {
return conn, nil
}
c := m.createMuxedConn(ufrag, candidateID)View on GitHub (pinned to 93e97f4bf1)
Solutions
- Bind the mux's UDPConn to an unspecified address (0.0.0.0 or [::]) so the strict equality check is skipped
- Pass exactly the address reported by the conn's LocalAddr()/GetListenAddresses()
- Align the address family of candidates with the bound socket family
- Re-create the mux with a correctly bound UDPConn
Example fix
// before: bound to a specific IP
conn, _ := net.ListenUDP("udp4", &net.UDPAddr{IP: net.ParseIP("192.0.2.10"), Port: 3478})
mux, _ := NewSingleSocketUDPMux(Params{UDPConn: conn})
c, err := mux.GetConn(ufrag, raddr, cid) // raddr from another interface -> invalid address
// after: unspecified bind skips the equality check
conn, _ := net.ListenUDP("udp4", &net.UDPAddr{Port: 3478})
mux, _ := NewSingleSocketUDPMux(Params{UDPConn: conn})
c, err := mux.GetConn(ufrag, raddr, cid) Defensive patterns
Strategy: validation
Validate before calling
local := udpConn.LocalAddr().String()
unspecified := false
if ua, ok := udpConn.LocalAddr().(*net.UDPAddr); ok {
unspecified = ua.IP.IsUnspecified()
}
if !unspecified && addr.String() != local {
return fmt.Errorf("skipping GetConn: %s is not the mux bind address %s", addr, local)
} Prevention
- Bind ICE/mux sockets to unspecified addresses when candidates can arrive on any interface
- Normalize addresses with Unmap() before comparing strings
- Use one mux per bind address; never share a mux across interfaces
When it happens
Trigger: Creating the mux from a UDPConn bound to a specific interface IP, then calling GetConn with a candidate address from another interface or family (v4 vs v6, LAN IP vs loopback); an ICE candidate arriving whose address differs from the bind address.
Common situations: Bind address pinned to one IP while the peer reaches the host via another address; dual-stack mismatch; tests using 127.0.0.1 against a mux bound to the LAN address.
Related errors
- proxy_protocol is not supported for UDP services
- failed to get OAuth flow: %v
- getting a request OAuth flow info failed: %v
- dial %s: %w
- parse address %s: %w
AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16).
Data as JSON: /api/errors/8bc91fdbd8a602c8.
Report an issue: GitHub.