netbirdio/netbird · error
converting file to packet conn failed: %w
Error message
converting file to packet conn failed: %w
What it means
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.
Source
Thrown at client/iface/wgproxy/rawsocket/rawsocket.go:85
log.Warnf("failed to close raw socket fd: %v", closeErr)
}
return nil, fmt.Errorf("setting fwmark failed: %w", err)
}
// Convert the file descriptor to a PacketConn.
file := os.NewFile(uintptr(fd), fmt.Sprintf("fd %d", fd))
if file == nil {
if closeErr := syscall.Close(fd); closeErr != nil {
log.Warnf("failed to close raw socket fd: %v", closeErr)
}
return nil, fmt.Errorf("converting fd to file failed")
}
packetConn, err := net.FilePacketConn(file)
if err != nil {
if closeErr := file.Close(); closeErr != nil {
log.Warnf("failed to close file: %v", closeErr)
}
return nil, fmt.Errorf("converting file to packet conn failed: %w", err)
}
// Close the original file to release the FD (net.FilePacketConn duplicates it)
if closeErr := file.Close(); closeErr != nil {
log.Warnf("failed to close file after creating packet conn: %v", closeErr)
}
return packetConn, nil
}
View on GitHub (pinned to 93e97f4bf1)
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
Defensive patterns
Strategy: validation
Validate before calling
// fd headroom check before opening raw sockets
func fdHeadroom(want int) bool {
var lim syscall.Rlimit
if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &lim); err != nil {
return true
}
used := 0
if ents, err := os.ReadDir("/proc/self/fd"); err == nil {
used = len(ents)
}
return uint64(used+want) < lim.Cur
} Try / catch
if _, err := net.FilePacketConn(file); err != nil {
if errors.Is(err, syscall.EMFILE) || errors.Is(err, syscall.ENFILE) {
log.Errorf("fd limit reached; raise ulimit -n: %v", err)
}
return fmt.Errorf("packet conn: %w", err)
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- setting fwmark failed: %w
- converting fd to file failed
- add IP to ipset: %w
- create ipset: %w
- failed to check rule: %w
AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16).
Data as JSON: /api/errors/32b3883a192345cf.
Report an issue: GitHub.