{"record":{"id":"32b3883a192345cf","repo":"netbirdio/netbird","slug":"converting-file-to-packet-conn-failed-w","errorCode":null,"errorMessage":"converting file to packet conn failed: %w","messagePattern":"converting file to packet conn failed: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/iface/wgproxy/rawsocket/rawsocket.go","lineNumber":85,"sourceCode":"\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\n\t// Close the original file to release the FD (net.FilePacketConn duplicates it)\n\tif closeErr := file.Close(); closeErr != nil {\n\t\tlog.Warnf(\"failed to close file after creating packet conn: %v\", closeErr)\n\t}\n\n\treturn packetConn, nil\n}\n","sourceCodeStart":67,"sourceCodeEnd":95,"githubUrl":"https://github.com/netbirdio/netbird/blob/93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c/client/iface/wgproxy/rawsocket/rawsocket.go#L67-L95","documentation":"Returned by rawsocket.prepareSenderRawSocket when net.FilePacketConn(file) fails. FilePacketConn duplicates the fd with dup() and requires the fd to actually be a packet socket; failure is almost always EMFILE/ENFILE (fd exhaustion at the dup) or, if the fd was somehow closed in between, EBADF/ENOTSOCK. The raw socket is required (IPv4) for the eBPF proxy and the SrcFaker, so Listen()/NewSrcFaker aborts.","triggerScenarios":"Process at its open-file limit when creating the raw socket - common in the UDP proxy path where each peer redirect (RedirectAs -> NewSrcFaker) opens one raw socket; long-lived agents with many relays/peers leaking fds; low `ulimit -n` in containers or systemd unit.","commonSituations":"Agents with many peers churning direct/relay paths over days; container defaults of 1024 fds; other software on the host inflating the fd count; leaks from previous failed NewSrcFaker paths.","solutions":["Check and raise the fd limit: `ulimit -n` / `systemctl edit netbird` with LimitNOFILE=65536, or `--ulimit nofile=65536:65536` for containers","Count the agent's fds: `ls /proc/$(pgrep -x netbird)/fd | wc -l` - steady growth indicates the SrcFaker sockets are not being closed","Restart the agent to recover immediately once limits are raised","If not fd exhaustion, read the wrapped errno from the %w chain: ENOTSOCK means the fd was already closed elsewhere"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// fd headroom check before opening raw sockets\nfunc fdHeadroom(want int) bool {\n    var lim syscall.Rlimit\n    if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &lim); err != nil {\n        return true\n    }\n    used := 0\n    if ents, err := os.ReadDir(\"/proc/self/fd\"); err == nil {\n        used = len(ents)\n    }\n    return uint64(used+want) < lim.Cur\n}","typeGuard":null,"tryCatchPattern":"if _, err := net.FilePacketConn(file); err != nil {\n    if errors.Is(err, syscall.EMFILE) || errors.Is(err, syscall.ENFILE) {\n        log.Errorf(\"fd limit reached; raise ulimit -n: %v\", err)\n    }\n    return fmt.Errorf(\"packet conn: %w\", err)\n}","preventionTips":["Set LimitNOFILE=65536 (systemd) or --ulimit nofile (docker) for long-lived agents","Watch /proc/<pid>/fd growth when peers churn between relay and direct paths - SrcFaker sockets are the usual leak","Close failed SrcFaker/proxy objects eagerly instead of relying on GC"],"tags":["go","netbird","raw-socket","fd-exhaustion","linux"],"backgroundTag":null,"analyzedSha":"93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c","analyzedAt":"2026-08-16T03:09:19.136Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}