{"record":{"id":"2aad995c1fd35848","repo":"slackhq/nebula","slug":"so-reuseport-failed-v-2aad99","errorCode":null,"errorMessage":"SO_REUSEPORT failed: %v","messagePattern":"SO_REUSEPORT failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"udp/udp_netbsd.go","lineNumber":28,"sourceCode":"\t\"log/slog\"\n\t\"net\"\n\t\"syscall\"\n\n\t\"golang.org/x/sys/unix\"\n)\n\nfunc NewListener(l *slog.Logger, s Settings) (Conn, error) {\n\treturn NewGenericListener(l, s)\n}\n\nfunc NewListenConfig(multi bool) net.ListenConfig {\n\treturn net.ListenConfig{\n\t\tControl: func(network, address string, c syscall.RawConn) error {\n\t\t\tif multi {\n\t\t\t\tvar controlErr error\n\t\t\t\terr := c.Control(func(fd uintptr) {\n\t\t\t\t\tif err := syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, unix.SO_REUSEPORT, 1); err != nil {\n\t\t\t\t\t\tcontrolErr = fmt.Errorf(\"SO_REUSEPORT failed: %v\", err)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\tif controlErr != nil {\n\t\t\t\t\treturn controlErr\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn nil\n\t\t},\n\t}\n}\n\nfunc (u *GenericConn) Rebind() error {\n\treturn nil\n}","sourceCodeStart":10,"sourceCodeEnd":46,"githubUrl":"https://github.com/slackhq/nebula/blob/dd8f660c0ac37903ec4080ca4d3c861ba9342ceb/udp/udp_netbsd.go#L10-L46","documentation":"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.","triggerScenarios":"Starting nebula on NetBSD with multiple listeners (SO_REUSEPORT desired) on a kernel/runtime where setsockopt(SOL_SOCKET, SO_REUSEPORT) fails.","commonSituations":"Older NetBSD releases lacking SO_REUSEPORT; systrace/pledge-like restrictions; porting issues when the Control callback runs with a non-socket fd.","solutions":["Upgrade NetBSD to a release supporting SO_REUSEPORT on UDP sockets","Configure a single listener so the multi/SO_REUSEPORT path is skipped","Check the %v-formatted inner errno to identify the exact setsockopt failure","Report upstream if it reproduces on a supported NetBSD release"],"exampleFix":"// before\nlisten:\n  multi: true\n// after\nlisten:\n  multi: false","handlingStrategy":"fallback","validationCode":"// on NetBSD, probe SO_REUSEPORT support before enabling multi\ns, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_DGRAM, syscall.IPPROTO_UDP)\nif err == nil {\n    err = syscall.SetsockoptInt(s, syscall.SOL_SOCKET, unix.SO_REUSEPORT, 1)\n    syscall.Close(s)\n}\nuseMulti := err == nil","typeGuard":null,"tryCatchPattern":"l, err := udp.NewListener(cfgMulti)\nif err != nil && strings.Contains(err.Error(), \"SO_REUSEPORT failed\") {\n    l, err = udp.NewListener(cfgSingle) // retry without multi\n}","preventionTips":["Default to single-listener mode on NetBSD","Probe setsockopt(SO_REUSEPORT) support at startup before enabling multi","Pin to NetBSD releases with UDP SO_REUSEPORT support","Remember the error is %v-wrapped: match on message text, not errors.Is"],"tags":["udp","netbsd","so-reuseport","setsockopt","bsd"],"backgroundTag":"so-reuseport-failed","analyzedSha":"dd8f660c0ac37903ec4080ca4d3c861ba9342ceb","analyzedAt":"2026-09-03T11:13:55.444Z","contentChangedAt":"2026-09-03T11:13:55.444Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}