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

  1. Bind the listener dual-stack or to an IPv6 address (::) if IPv6 peers must be reached
  2. Remove/avoid IPv6 addresses in nebula's config (preferred_addresses/ranges) when the host has no IPv6 connectivity
  3. Force remote resolution to A records (IPv4) so WriteTo never receives a v6 address
  4. 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

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


AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03). Data as JSON: /api/errors/bcbeb42c10d1ad53. Report an issue: GitHub.