netbirdio/netbird · warning
address %s is part of the NetBird network %s, refusing to wr
Error message
address %s is part of the NetBird network %s, refusing to write
What it means
UDPConn.WriteTo on the universal UDP mux refuses datagrams whose destination falls inside the NetBird overlay network (the v4 Network or v6 IPv6Net prefixes attached to that shared underlay socket). The mux carries peer/ICE underlay traffic; writing to an overlay address would send underlay packets into the tunnel and create a routing loop, so the guard logs a warning and returns this error with zero bytes written.
Source
Thrown at client/iface/udpmux/universal.go:131
mux *UniversalUDPMuxDefault
logger logging.LeveledLogger
address wgaddr.Address
}
// GetPacketConn returns the underlying PacketConn
func (u *UDPConn) GetPacketConn() net.PacketConn {
return u.PacketConn
}
func (u *UDPConn) WriteTo(b []byte, addr net.Addr) (int, error) {
udpAddr, ok := addr.(*net.UDPAddr)
if !ok {
return u.PacketConn.WriteTo(b, addr)
}
dst := udpAddr.AddrPort().Addr().Unmap()
if (u.address.Network.IsValid() && u.address.Network.Contains(dst)) || (u.address.IPv6Net.IsValid() && u.address.IPv6Net.Contains(dst)) {
log.Warnf("address %s is part of the NetBird network %s, refusing to write", addr, u.address)
return 0, fmt.Errorf("address %s is part of the NetBird network %s, refusing to write", addr, u.address)
}
return u.PacketConn.WriteTo(b, addr)
}
// GetSharedConn returns the shared udp conn
func (m *UniversalUDPMuxDefault) GetSharedConn() net.PacketConn {
return m.params.UDPConn
}
// GetListenAddresses returns the listen addr of this UDP
func (m *UniversalUDPMuxDefault) GetListenAddresses() []net.Addr {
return []net.Addr{m.LocalAddr()}
}
// GetRelayedAddr creates relayed connection to the given TURN service and returns the relayed addr.
// Not implemented yet.
func (m *UniversalUDPMuxDefault) GetRelayedAddr(turnAddr net.Addr, deadline time.Duration) (*net.Addr, error) {
return nil, fmt.Errorf("not implemented yet")View on GitHub (pinned to 93e97f4bf1)
Solutions
- Ensure relay/management/peer hostnames resolve to underlay addresses, not overlay IPs
- Do not reuse the mux's shared conn for application traffic
- Check the configured network ranges for accidental overlap with the intended destination space
- After fixing, verify WriteTo destinations sit outside both overlay prefixes
Example fix
// before
target := resolve("relay.example.net") // returned 100.96.4.7, an overlay IP
_, err := sharedConn.WriteTo(pkt, target) // refused, 0 bytes
// after
target := resolveUnderlay("relay.example.net") // public/underlay IP enforced
_, err := sharedConn.WriteTo(pkt, target) Defensive patterns
Strategy: validation
Validate before calling
func isOverlayDestination(dst netip.Addr, v4, v6 netip.Prefix) bool {
dst = dst.Unmap()
return (v4.IsValid() && v4.Contains(dst)) || (v6.IsValid() && v6.Contains(dst))
}
if isOverlayDestination(udpAddr.AddrPort().Addr(), overlayV4, overlayV6) {
return fmt.Errorf("refusing overlay destination %s", udpAddr)
} Prevention
- Never dial overlay IPs over the shared underlay conn
- Keep DNS for management and relay hostnames pointing at underlay addresses
- Re-check network ranges whenever the overlay address space changes
When it happens
Trigger: WriteTo with a destination inside the configured NetBird range: a relay or peer endpoint resolved to its overlay IP (100.64/10-style or the v6 ULA), or application code reusing the shared conn (GetSharedConn) to dial overlay addresses.
Common situations: DNS returning the overlay IP for a management or relay hostname; a stale network map mixing overlay IPs into underlay candidates; user code grabbing the shared conn for application data.
Related errors
- failed to verify signature of artifact keys
- no keys found in bundle
- failed to decode PEM data
- revocation list verification failed
- proxy_protocol is not supported for UDP services
AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16).
Data as JSON: /api/errors/15c5ecf3f7b455be.
Report an issue: GitHub.