{"record":{"id":"e19db68705c85e25","repo":"cilium/cilium","slug":"setsockopt-so-mark-failed-w","errorCode":null,"errorMessage":"setsockopt(SO_MARK) failed: %w","messagePattern":"setsockopt\\(SO_MARK\\) failed: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"pkg/fqdn/dnsproxy/udp.go","lineNumber":108,"sourceCode":"\t}\n\n\treturn nil\n}\n\n// listenConfig sets the socket options for the fqdn proxy transparent socket.\n// Note that it is also used for TCP sockets.\nfunc listenConfig(mark uint32, ipFamily ipfamily.IPFamily) *net.ListenConfig {\n\treturn &net.ListenConfig{\n\t\tControl: func(_, _ string, c syscall.RawConn) error {\n\t\t\tvar opErr error\n\t\t\terr := c.Control(func(fd uintptr) {\n\t\t\t\tif err := transparentSetsockopt(int(fd), ipFamily); err != nil {\n\t\t\t\t\topErr = err\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif mark != 0 {\n\t\t\t\t\tif err := unix.SetsockoptUint64(int(fd), unix.SOL_SOCKET, unix.SO_MARK, uint64(mark)); err != nil {\n\t\t\t\t\t\topErr = fmt.Errorf(\"setsockopt(SO_MARK) failed: %w\", 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 := unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_REUSEADDR, 1); err != nil {\n\t\t\t\t\topErr = fmt.Errorf(\"setsockopt(SO_REUSEADDR) failed: %w\", err)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif !option.Config.EnableBPFTProxy {\n\t\t\t\t\tif err := unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_REUSEPORT, 1); err != nil {\n\t\t\t\t\t\topErr = fmt.Errorf(\"setsockopt(SO_REUSEPORT) failed: %w\", err)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n","sourceCodeStart":90,"sourceCodeEnd":126,"githubUrl":"https://github.com/cilium/cilium/blob/ac7b90affa4baf0642e6685319d56907b3a73a6d/pkg/fqdn/dnsproxy/udp.go#L90-L126","documentation":"listenConfig marks sockets with a magic fwmark (e.g. MagicMarkEgress 0x0b00) so the kernel/BPF datapath recognizes proxy return traffic and routes it correctly. Setting SO_MARK requires CAP_NET_ADMIN; failure produces 'setsockopt(SO_MARK) failed: %w' and the socket is not created.","triggerScenarios":"Any listen/bind through listenConfig with mark != 0 (e.g. bindResponseUDPConnection) on a system where SetsockoptUint64(SO_MARK) fails — EPERM without CAP_NET_ADMIN, or kernels/runtimes where SO_MARK is blocked (some seccomp profiles, older WSL/gVisor).","commonSituations":"Containers missing NET_ADMIN, security profiles blocking SO_MARK, or non-mainstream kernels (some cloud sandboxed runtimes) that do not implement SO_MARK.","solutions":["Add CAP_NET_ADMIN to the container securityContext","Allow setsockopt(SO_MARK) in seccomp/apparmor policy","Verify kernel support: SO_MARK requires Linux ≥ 2.6.25; SetsockoptUint64 form needs a recent kernel/libc (SO_MARK as u64 since 5.17, otherwise pass u32 via SetsockoptInt)","Check the wrapped errno: EPERM → capability missing"],"exampleFix":"// before\ncapabilities:\n  add: [\"SYS_ADMIN\"]\n// after\ncapabilities:\n  add: [\"SYS_ADMIN\", \"NET_ADMIN\", \"NET_RAW\"]","handlingStrategy":"validation","validationCode":"// SO_MARK requires CAP_NET_ADMIN\nif !hasCap_NET_ADMIN() {\n    return errors.New(\"setting SO_MARK requires CAP_NET_ADMIN\")\n}","typeGuard":"func isMarkSockoptError(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"setsockopt(SO_MARK)\")\n}","tryCatchPattern":"if err := listenConfig(mark, family).ListenPacket(ctx, \"ip:udp\", addr); err != nil {\n    if isMarkSockoptError(err) {\n        return fmt.Errorf(\"cannot fwmark proxy sockets (need CAP_NET_ADMIN): %w\", err)\n    }\n    return err\n}","preventionTips":["Add NET_ADMIN capability wherever fwmark 0x0b00 egress marking is required","Test socket creation under the production securityContext in CI","Keep kernels recent enough for SetsockoptUint64(SO_MARK) (≥5.17 semantics) or use SetsockoptInt on older kernels"],"tags":["linux","setsockopt","fwmark","capabilities"],"backgroundTag":"setsockopt-permission-denied","analyzedSha":"ac7b90affa4baf0642e6685319d56907b3a73a6d","analyzedAt":"2026-08-31T18:27:15.868Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}