{"record":{"id":"c8d084d48d02eb0c","repo":"netbirdio/netbird","slug":"setting-fwmark-failed-w","errorCode":null,"errorMessage":"setting fwmark failed: %w","messagePattern":"setting fwmark failed: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/iface/wgproxy/rawsocket/rawsocket.go","lineNumber":69,"sourceCode":"\t\t}\n\t}\n\n\t// Bind the socket to the \"lo\" interface.\n\terr = syscall.SetsockoptString(fd, syscall.SOL_SOCKET, syscall.SO_BINDTODEVICE, \"lo\")\n\tif err != nil {\n\t\tif closeErr := syscall.Close(fd); closeErr != nil {\n\t\t\tlog.Warnf(\"failed to close raw socket fd: %v\", closeErr)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"binding to lo interface failed: %w\", err)\n\t}\n\n\t// Set the fwmark on the socket.\n\terr = nbnet.SetSocketOpt(fd)\n\tif err != nil {\n\t\tif closeErr := syscall.Close(fd); closeErr != nil {\n\t\t\tlog.Warnf(\"failed to close raw socket fd: %v\", closeErr)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"setting fwmark failed: %w\", err)\n\t}\n\n\t// Convert the file descriptor to a PacketConn.\n\tfile := os.NewFile(uintptr(fd), fmt.Sprintf(\"fd %d\", fd))\n\tif file == nil {\n\t\tif closeErr := syscall.Close(fd); closeErr != nil {\n\t\t\tlog.Warnf(\"failed to close raw socket fd: %v\", closeErr)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"converting fd to file failed\")\n\t}\n\tpacketConn, err := net.FilePacketConn(file)\n\tif err != nil {\n\t\tif closeErr := file.Close(); closeErr != nil {\n\t\t\tlog.Warnf(\"failed to close file: %v\", closeErr)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"converting file to packet conn failed: %w\", err)\n\t}\n","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/netbirdio/netbird/blob/93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c/client/iface/wgproxy/rawsocket/rawsocket.go#L51-L87","documentation":"Returned by rawsocket.prepareSenderRawSocket when nbnet.SetSocketOpt(fd) fails. SetSocketOpt only acts when AdvancedRouting() is enabled, and then performs syscall.SetsockoptInt(fd, SOL_SOCKET, SO_MARK, ControlPlaneMark). SO_MARK requires CAP_NET_ADMIN on kernels < 5.17 and CAP_NET_RAW on 5.17+. The socket being marked is the raw socket used to fake packet source addresses for the WG proxy, so a failed mark aborts socket creation and with it eBPF proxy Listen() or SrcFaker construction.","triggerScenarios":"Agent (or a test binary) run without root and without CAP_NET_ADMIN/CAP_NET_RAW while advanced routing is active (routing table != default or the env toggle enabled); container dropping capabilities; seccomp filtering setsockopt(SO_MARK).","commonSituations":"Running netbird or its unit/integration harness as a non-root user; Docker/podman containers started without --cap-add=NET_ADMIN; hardening profiles (systemd ProtectKernelDefaults-adjacent, AppArmor) blocking SO_MARK.","solutions":["Run the agent as root or grant CAP_NET_RAW and CAP_NET_ADMIN (kernel >= 5.17 needs only CAP_NET_RAW): `sudo setcap cap_net_raw,cap_net_admin+ep ./netbird` or run via the packaged service","For containers, start with NET_ADMIN capability or run the container privileged like the official image does","If SO_MARK is genuinely unavailable, disable advanced routing for the agent so AdvancedRouting() returns false and the call becomes a no-op","Verify with a quick probe: `python3 -c \"import socket; s=socket.socket(2,3,255); s.setsockopt(1,36,0x162)\"` succeeding means caps are fine"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// capability preflight before creating the proxy\nfunc canMarkSockets() bool {\n    fd, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_RAW, syscall.IPPROTO_RAW)\n    if err != nil {\n        return false\n    }\n    defer syscall.Close(fd)\n    return syscall.SetsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_MARK, 0x162) == nil\n}","typeGuard":null,"tryCatchPattern":"if _, err := rawsocket.PrepareSenderRawSocketIPv4(); err != nil {\n    if strings.Contains(err.Error(), \"setting fwmark failed\") {\n        return fmt.Errorf(\"raw socket needs CAP_NET_ADMIN (or CAP_NET_RAW on linux >= 5.17): %w\", err)\n    }\n    return err\n}","preventionTips":["Run the agent as root or with cap_net_raw+cap_net_admin on the binary/service unit","In containers, pass --cap-add=NET_ADMIN or use the official privileged image","If SO_MARK cannot be granted, disable advanced routing so AdvancedRouting() short-circuits the mark"],"tags":["go","netbird","raw-socket","fwmark","capabilities","linux"],"backgroundTag":null,"analyzedSha":"93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c","analyzedAt":"2026-08-16T03:09:19.136Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}