slackhq/nebula · error

SO_REUSEPORT failed: %v

Error message

SO_REUSEPORT failed: %v

What it means

On NetBSD, the listener's Control function sets SO_REUSEPORT on the raw fd before bind when multi-listening is requested; if setsockopt fails it records this error (with %v formatting, not unwrappable). This aborts listen creation for that socket.

Source

Thrown at udp/udp_netbsd.go:28

	"log/slog"
	"net"
	"syscall"

	"golang.org/x/sys/unix"
)

func NewListener(l *slog.Logger, s Settings) (Conn, error) {
	return NewGenericListener(l, s)
}

func NewListenConfig(multi bool) net.ListenConfig {
	return net.ListenConfig{
		Control: func(network, address string, c syscall.RawConn) error {
			if multi {
				var controlErr error
				err := c.Control(func(fd uintptr) {
					if err := syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, unix.SO_REUSEPORT, 1); err != nil {
						controlErr = fmt.Errorf("SO_REUSEPORT failed: %v", err)
						return
					}
				})
				if err != nil {
					return err
				}
				if controlErr != nil {
					return controlErr
				}
			}
			return nil
		},
	}
}

func (u *GenericConn) Rebind() error {
	return nil
}

View on GitHub (pinned to dd8f660c0a)

Solutions

  1. Upgrade NetBSD to a release supporting SO_REUSEPORT on UDP sockets
  2. Configure a single listener so the multi/SO_REUSEPORT path is skipped
  3. Check the %v-formatted inner errno to identify the exact setsockopt failure
  4. Report upstream if it reproduces on a supported NetBSD release

Example fix

// before
listen:
  multi: true
// after
listen:
  multi: false
Defensive patterns

Strategy: fallback

Validate before calling

// on NetBSD, probe SO_REUSEPORT support before enabling multi
s, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_DGRAM, syscall.IPPROTO_UDP)
if err == nil {
    err = syscall.SetsockoptInt(s, syscall.SOL_SOCKET, unix.SO_REUSEPORT, 1)
    syscall.Close(s)
}
useMulti := err == nil

Try / catch

l, err := udp.NewListener(cfgMulti)
if err != nil && strings.Contains(err.Error(), "SO_REUSEPORT failed") {
    l, err = udp.NewListener(cfgSingle) // retry without multi
}

Prevention

When it happens

Trigger: Starting nebula on NetBSD with multiple listeners (SO_REUSEPORT desired) on a kernel/runtime where setsockopt(SOL_SOCKET, SO_REUSEPORT) fails.

Common situations: Older NetBSD releases lacking SO_REUSEPORT; systrace/pledge-like restrictions; porting issues when the Control callback runs with a non-socket fd.

Related errors


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