slackhq/nebula · error

SO_REUSEPORT failed: %v

Error message

SO_REUSEPORT failed: %v

What it means

On Android, nebula's UDP listen path sets SO_REUSEPORT on the socket fd via the net.ListenConfig Control hook so multiple sockets can bind the same port. If syscall.SetsockoptInt fails, the error is wrapped as 'SO_REUSEPORT failed'. This typically reflects a kernel or SELinux restriction rather than application misuse.

Source

Thrown at udp/udp_android.go:26

	"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. Update the device/OS to a kernel >= 3.9 that supports SO_REUSEPORT
  2. Check SELinux denials (dmesg / adb logcat for avc denied) and adjust the policy or run in permissive mode for testing
  3. Run with multi=false if lightfire/multiple-socket binding is not needed, so the socket option is skipped
  4. Verify the error value (permission denied vs invalid argument) to target the actual restriction
Defensive patterns

Strategy: fallback

Validate before calling

// Before relying on multi-socket binding, confirm kernel support:
// grep -q SO_REUSEPORT /proc/kallsyms 2>/dev/null || uname -r (require >= 3.9)
// On Android also check `adb shell getenforce` for SELinux enforcing mode

Try / catch

ln, err := listenUDP(lc, "0.0.0.0:0")
if err != nil {
	if strings.Contains(err.Error(), "SO_REUSEPORT failed") {
		// fall back to a single socket (multi=false) or surface a device/kernel requirement
		return listenSingle()
	}
	return err
}

Prevention

When it happens

Trigger: Creating a UDP listener with multi=true on Android when setsockopt(SOL_SOCKET, SO_REUSEPORT) returns an error — e.g. kernel lacking SO_REUSEPORT support, permission denied from SELinux policy, or fd validity issues.

Common situations: Running nebula on very old Android kernels (<3.9) without SO_REUSEPORT; hardened SELinux policies blocking socket options; custom ROMs with restricted network syscalls.

Related errors


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