{"record":{"id":"e605f4906053dfc3","repo":"cilium/cilium","slug":"failed-to-setsockopt-so-reuseport-w","errorCode":null,"errorMessage":"failed to setsockopt(SO_REUSEPORT): %w","messagePattern":"failed to setsockopt\\(SO_REUSEPORT\\): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"daemon/healthz/sockopt.go","lineNumber":30,"sourceCode":"\n// setsockoptReuseAddrAndPort sets the SO_REUSEADDR and SO_REUSEPORT socket options on c's\n// underlying socket in order to improve the chance to re-bind to the same address and port\n// upon restart.\nfunc setsockoptReuseAddrAndPort(network, address string, c syscall.RawConn) error {\n\tvar soerr error\n\tif err := c.Control(func(su uintptr) {\n\t\ts := int(su)\n\t\t// Allow reuse of recently-used addresses. This socket option is\n\t\t// set by default on listeners in Go's net package, see\n\t\t// net setDefaultListenerSockopts\n\t\tif err := unix.SetsockoptInt(s, unix.SOL_SOCKET, unix.SO_REUSEADDR, 1); err != nil {\n\t\t\tsoerr = fmt.Errorf(\"failed to setsockopt(SO_REUSEADDR): %w\", err)\n\t\t\treturn\n\t\t}\n\t\t// Allow reuse of recently-used ports. This gives the agent a\n\t\t// better chance to re-bind upon restarts.\n\t\tif err := unix.SetsockoptInt(s, unix.SOL_SOCKET, unix.SO_REUSEPORT, 1); err != nil {\n\t\t\tsoerr = fmt.Errorf(\"failed to setsockopt(SO_REUSEPORT): %w\", err)\n\t\t}\n\t}); err != nil {\n\t\treturn err\n\t}\n\treturn soerr\n}\n","sourceCodeStart":12,"sourceCodeEnd":37,"githubUrl":"https://github.com/cilium/cilium/blob/ac7b90affa4baf0642e6685319d56907b3a73a6d/daemon/healthz/sockopt.go#L12-L37","documentation":"Companion to the SO_REUSEADDR case: setsockoptReuseAddrAndPort also sets SO_REUSEPORT so the agent can re-bind the same port after restarts (useful when kube-proxy or the previous agent instance still holds it). Failure of unix.SetsockoptInt(SOL_SOCKET, SO_REUSEPORT, 1) is wrapped into this error and fails listener setup.","triggerScenarios":"The Control callback runs during Listen and SetsockoptInt for SO_REUSEPORT returns an error — typically denied by seccomp/LSM or an unsupported kernel/platform combination.","commonSituations":"Hardened seccomp profiles blocking SO_REUSEPORT; very old kernels lacking SO_REUSEPORT semantics; sandboxed runtimes (gVisor/kata) with incomplete socket-option support.","solutions":["Allow setsockopt(SOL_SOCKET, SO_REUSEPORT) in the seccomp/LSM profile for the cilium agent","Verify kernel version supports SO_REUSEPORT (>=3.9) and the runtime honors it","As a workaround, drop the SO_REUSEPORT call and instead ensure the port is free before start (stop conflicting kube-proxy)","Report the runtime/kernel combination if options are systematically unsupported"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// verify kernel support before relying on SO_REUSEPORT\nif !kernelSupportsReusePort() { // e.g. parse uname -r >= 3.9 and test setsockopt\n\tlog.Warn(\"SO_REUSEPORT unsupported; ensure the port is free before start\")\n}","typeGuard":null,"tryCatchPattern":"if err := setsockoptReuseAddrAndPort(nil, \"tcp\", nil); err != nil {\n\tif errors.Is(err, unix.ENOPROTOOPT) || errors.Is(err, unix.EPERM) {\n\t\tlog.WithError(err).Warn(\"SO_REUSEPORT unavailable; falling back\")\n\t}\n}","preventionTips":["Ensure kernel >= 3.9 and runtime honors SO_REUSEPORT (avoid gVisor limitations)","Allow the option in seccomp profiles","Stop conflicting processes holding the port when falling back","Pin ports and coordinate restarts to avoid double-bind races"],"tags":["sockets","setsockopt","so-reuseport","security"],"backgroundTag":"setsockopt-failed","analyzedSha":"ac7b90affa4baf0642e6685319d56907b3a73a6d","analyzedAt":"2026-08-31T18:27:15.868Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}