slackhq/nebula · error
unable to set SO_REUSEPORT: %w
Error message
unable to set SO_REUSEPORT: %w
What it means
NewListener sets SO_REUSEPORT so multiple nebula processes/threads can bind the same UDP port, and wraps the setsockopt(2) errno if the kernel rejects it. The fd is closed and listener creation aborts. The wrapped value is the raw errno from unix.SetsockoptInt.
Source
Thrown at udp/udp_linux.go:54
func NewListener(l *slog.Logger, s Settings) (Conn, error) {
af := unix.AF_INET6
if s.Listen.Addr().Is4() {
af = unix.AF_INET
}
syscall.ForkLock.RLock()
fd, err := unix.Socket(af, unix.SOCK_DGRAM, unix.IPPROTO_UDP)
if err == nil {
unix.CloseOnExec(fd)
}
syscall.ForkLock.RUnlock()
if err != nil {
return nil, fmt.Errorf("unable to open socket: %w", err)
}
if s.Multi {
if err = unix.SetsockoptInt(fd, unix.SOL_SOCKET, unix.SO_REUSEPORT, 1); err != nil {
_ = unix.Close(fd)
return nil, fmt.Errorf("unable to set SO_REUSEPORT: %w", err)
}
}
var sa unix.Sockaddr
port := int(s.Listen.Port())
if s.Listen.Addr().Is4() {
sa4 := &unix.SockaddrInet4{Port: port}
sa4.Addr = s.Listen.Addr().As4()
sa = sa4
} else {
sa6 := &unix.SockaddrInet6{Port: port}
sa6.Addr = s.Listen.Addr().As16()
sa = sa6
}
if err = unix.Bind(fd, sa); err != nil {
_ = unix.Close(fd)
return nil, fmt.Errorf("unable to bind to socket: %w", err)
}View on GitHub (pinned to dd8f660c0a)
Solutions
- Check the wrapped errno to identify the exact failure and confirm the kernel supports SO_REUSEPORT (Linux >= 3.9)
- Disable the multi-listener option so Multi=false and SO_REUSEPORT is not requested
- Update to a newer kernel or run on a platform with full setsockopt support
- Audit seccomp/AppArmor profiles to allow setsockopt on SOL_SOCKET
Example fix
// before listeners: batch: 64 multi: true // after listeners: batch: 64 multi: false
Defensive patterns
Strategy: try-catch
Validate before calling
// feature check before enabling multi
if runtime.GOOS == "linux" {
var kv kernel.Version // from uname
if kv.LessThan(3, 9, 0) { disableMulti() }
} Try / catch
l, err := udp.NewListener(...)
if err != nil {
var soErr *fmt.Error // wrapped setsockopt errno
if strings.Contains(err.Error(), "SO_REUSEPORT") {
// fall back to single-listener config and retry
}
return err
} Prevention
- Only enable multi when all target kernels support SO_REUSEPORT (Linux >= 3.9)
- Keep seccomp profiles permissive for setsockopt on SOL_SOCKET
- Test on the oldest supported kernel in your fleet
- Prefer default (multi off) unless you need SO_REUSEPORT load spreading
When it happens
Trigger: Calling udp.NewListener with Multi=true (or config enabling multiple UDP listeners) when setsockopt(SO_REUSEPORT) fails on the fresh fd.
Common situations: Kernels or OS builds without SO_REUSEPORT support; seccomp filters blocking setsockopt; running under an OS emulation layer (e.g. old WSL1) that does not implement the option.
Related errors
- SO_REUSEPORT failed: %v
- unable to open socket: %w
- unable to bind to socket: %w
- unsupported sock type: %T
- WriteBatch: len(bufs)=%d != len(addrs)=%d
AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03).
Data as JSON: /api/errors/007c19ef5932292d.
Report an issue: GitHub.