{"record":{"id":"8bc91fdbd8a602c8","repo":"netbirdio/netbird","slug":"invalid-address-s","errorCode":null,"errorMessage":"invalid address %s","messagePattern":"invalid address (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/iface/udpmux/mux.go","lineNumber":251,"sourceCode":"\n\tm.mu.Lock()\n\tdefer m.mu.Unlock()\n\tif len(m.localAddrsForUnspecified) > 0 {\n\t\treturn slices.Clone(m.localAddrsForUnspecified)\n\t}\n\n\treturn []net.Addr{m.LocalAddr()}\n}\n\n// GetConn returns a PacketConn given the connection's ufrag and network address\n// creates the connection if an existing one can't be found\nfunc (m *SingleSocketUDPMux) GetConn(ufrag string, addr net.Addr, candidateID string) (net.PacketConn, error) {\n\t// don't check addr for mux using unspecified address\n\tm.mu.Lock()\n\tlenLocalAddrs := len(m.localAddrsForUnspecified)\n\tm.mu.Unlock()\n\tif lenLocalAddrs == 0 && m.params.UDPConn.LocalAddr().String() != addr.String() {\n\t\treturn nil, fmt.Errorf(\"invalid address %s\", addr.String())\n\t}\n\n\tvar isIPv6 bool\n\tif udpAddr, _ := addr.(*net.UDPAddr); udpAddr != nil && udpAddr.IP.To4() == nil {\n\t\tisIPv6 = true\n\t}\n\tm.mu.Lock()\n\tdefer m.mu.Unlock()\n\n\tif m.IsClosed() {\n\t\treturn nil, io.ErrClosedPipe\n\t}\n\n\tif conn, ok := m.getConn(ufrag, isIPv6); ok {\n\t\treturn conn, nil\n\t}\n\n\tc := m.createMuxedConn(ufrag, candidateID)","sourceCodeStart":233,"sourceCodeEnd":269,"githubUrl":"https://github.com/netbirdio/netbird/blob/93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c/client/iface/udpmux/mux.go#L233-L269","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before: bound to a specific IP\nconn, _ := net.ListenUDP(\"udp4\", &net.UDPAddr{IP: net.ParseIP(\"192.0.2.10\"), Port: 3478})\nmux, _ := NewSingleSocketUDPMux(Params{UDPConn: conn})\nc, err := mux.GetConn(ufrag, raddr, cid) // raddr from another interface -> invalid address\n\n// after: unspecified bind skips the equality check\nconn, _ := net.ListenUDP(\"udp4\", &net.UDPAddr{Port: 3478})\nmux, _ := NewSingleSocketUDPMux(Params{UDPConn: conn})\nc, err := mux.GetConn(ufrag, raddr, cid)","handlingStrategy":"validation","validationCode":"local := udpConn.LocalAddr().String()\nunspecified := false\nif ua, ok := udpConn.LocalAddr().(*net.UDPAddr); ok {\n    unspecified = ua.IP.IsUnspecified()\n}\nif !unspecified && addr.String() != local {\n    return fmt.Errorf(\"skipping GetConn: %s is not the mux bind address %s\", addr, local)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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"],"tags":["go","udp","mux","ice","network"],"backgroundTag":null,"analyzedSha":"93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c","analyzedAt":"2026-08-16T03:09:19.136Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}