cilium/cilium · critical
setsockopt(SO_MARK) failed: %w
Error message
setsockopt(SO_MARK) failed: %w
What it means
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.
Source
Thrown at pkg/fqdn/dnsproxy/udp.go:108
}
return nil
}
// listenConfig sets the socket options for the fqdn proxy transparent socket.
// Note that it is also used for TCP sockets.
func listenConfig(mark uint32, ipFamily ipfamily.IPFamily) *net.ListenConfig {
return &net.ListenConfig{
Control: func(_, _ string, c syscall.RawConn) error {
var opErr error
err := c.Control(func(fd uintptr) {
if err := transparentSetsockopt(int(fd), ipFamily); err != nil {
opErr = err
return
}
if mark != 0 {
if err := unix.SetsockoptUint64(int(fd), unix.SOL_SOCKET, unix.SO_MARK, uint64(mark)); err != nil {
opErr = fmt.Errorf("setsockopt(SO_MARK) failed: %w", err)
return
}
}
if err := unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_REUSEADDR, 1); err != nil {
opErr = fmt.Errorf("setsockopt(SO_REUSEADDR) failed: %w", err)
return
}
if !option.Config.EnableBPFTProxy {
if err := unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_REUSEPORT, 1); err != nil {
opErr = fmt.Errorf("setsockopt(SO_REUSEPORT) failed: %w", err)
return
}
}
})
if err != nil {
return err
}
View on GitHub (pinned to ac7b90affa)
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
Example fix
// before capabilities: add: ["SYS_ADMIN"] // after capabilities: add: ["SYS_ADMIN", "NET_ADMIN", "NET_RAW"]
Defensive patterns
Strategy: validation
Validate before calling
// SO_MARK requires CAP_NET_ADMIN
if !hasCap_NET_ADMIN() {
return errors.New("setting SO_MARK requires CAP_NET_ADMIN")
} Type guard
func isMarkSockoptError(err error) bool {
return err != nil && strings.Contains(err.Error(), "setsockopt(SO_MARK)")
} Try / catch
if err := listenConfig(mark, family).ListenPacket(ctx, "ip:udp", addr); err != nil {
if isMarkSockoptError(err) {
return fmt.Errorf("cannot fwmark proxy sockets (need CAP_NET_ADMIN): %w", err)
}
return err
} Prevention
- 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
When it happens
Trigger: 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).
Common situations: Containers missing NET_ADMIN, security profiles blocking SO_MARK, or non-mainstream kernels (some cloud sandboxed runtimes) that do not implement SO_MARK.
Related errors
- setsockopt(IP_TRANSPARENT) for %s failed: %w
- setsockopt(IP_RECVORIGDSTADDR) for %s failed: %w
- unable to create ipset %s: %w
- create netlink handle: %w
- setsockopt(SO_REUSEADDR) failed: %w
AI-assisted analysis of cilium/cilium@ac7b90affa (2026-08-31).
Data as JSON: /api/errors/e19db68705c85e25.
Report an issue: GitHub.