slackhq/nebula · error
ErrInvalidIPv6RemoteForSocket
ErrInvalidIPv6RemoteForSocket
Error message
listener is IPv4, but writing to IPv6 remote
What it means
ErrInvalidIPv6RemoteForSocket is nebula's udp package sentinel returned by WriteTo and writeSockaddr when the UDP socket was bound IPv4-only (u.isV4) but the caller attempts to send to an IPv6 address. The underlying sockaddr construction cannot represent an IPv6 destination on an AF_INET socket, so the write is refused up front.
Source
Thrown at udp/errors.go:5
package udp
import "errors"
var ErrInvalidIPv6RemoteForSocket = errors.New("listener is IPv4, but writing to IPv6 remote")
View on GitHub (pinned to dd8f660c0a)
Solutions
- Bind the listener dual-stack or to an IPv6 address (::) if IPv6 peers must be reached
- Remove/avoid IPv6 addresses in nebula's config (preferred_addresses/ranges) when the host has no IPv6 connectivity
- Force remote resolution to A records (IPv4) so WriteTo never receives a v6 address
- Check that udp_hostaddr/preferred ranges in config match the socket family actually bound
Example fix
// before (v4-only bind, v6 remote possible) udpConns, err := udp.NewListener(l, "0.0.0.0", port, true, 2) // after (dual-stack bind) udpConns, err := udp.NewListener(l, "::", port, true, 2)
Defensive patterns
Strategy: validation
Validate before calling
remote, err := netip.ParseAddr(remoteStr)
if err != nil {
return err
}
if listenerIsV4 && remote.Is6() {
return fmt.Errorf("cannot send to %s via IPv4-only socket", remote)
} Type guard
func canSendFromV4(remote netip.Addr) bool { return !remote.Is6() } Try / catch
err := udpConn.WriteTo(b, remote)
if errors.Is(err, udp.ErrInvalidIPv6RemoteForSocket) {
l.WithField("remote", remote).Warn("dropping packet: v4 socket, v6 remote")
return
} Prevention
- Match listener bind family to the set of remote addresses configured
- Avoid AAAA-only DNS names for peers when binding IPv4
- On v4-only hosts, strip IPv6 from preferred_addresses/ranges
- Prefer dual-stack (::) binds when both address families are in play
When it happens
Trigger: Calling udpConn.WriteTo (or the internal writeSockaddr path on darwin udp/udp_darwin.go:98 and linux udp/udp_linux.go:375) with an addr whose ip.Is6() is true while the listener was created with an IPv4-only bind address (e.g. 0.0.0.0 or a specific v4 address).
Common situations: Dual-stack misconfiguration: cert/config advertises or resolves an IPv6 nebula addr while the listener is bound to an IPv4 address; DNS resolving a hostname to an AAAA record for the remote; firewall/NAT environment forcing v4 bind but peer discovered via v6.
Related errors
- no outside connection
- ErrIPv6CouldNotFindPayload
- unable to find host
- unable to find host with relay
- no inside interface (tun)
AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03).
Data as JSON: /api/errors/bcbeb42c10d1ad53.
Report an issue: GitHub.