prometheus/node_exporter · error
failed to parse /proc/net/dev
Error message
failed to parse /proc/net/dev: %w
What it means
After opening procfs, procNetDevStats calls fs.NetDev() to parse /proc/net/dev. If parsing fails (unexpected file content or format), the error is wrapped as 'failed to parse /proc/net/dev'. procfs expects the kernel's documented net/dev format, so a parse failure signals either a non-standard kernel or that the path points at something that is not a real /proc/net/dev.
Solutions
- Verify cat /host/proc/net/dev (or your configured path) shows the standard two-header-line format with rx/tx columns.
- Confirm the mount is genuine host procfs, not a copied/overlay directory.
- Upgrade node_exporter/procfs library, then retry — parser tolerance changes between releases.
- Inspect the wrapped inner error to see the line or field that failed to parse.
- If running under gVisor/LXC, test the same collector on plain Linux to confirm the environment is the cause.
Defensive patterns
Strategy: validation
Validate before calling
// preflight: file must look like kernel /proc/net/dev
b, err := os.ReadFile(filepath.Join(*procPath, "net", "dev"))
if err != nil { return err }
lines := strings.Split(string(b), "\n")
if len(lines) < 3 || !strings.Contains(lines[0], "bytes") || !strings.Contains(lines[1], "packets") {
return fmt.Errorf("%s/net/dev has unexpected format", *procPath)
} Try / catch
err := collector.Update(ch)
if err != nil && strings.Contains(err.Error(), "failed to parse /proc/net/dev") {
logger.Error("procfs parse failed; environment likely non-standard (gVisor/LXC?)", "err", err)
return nil
} Prevention
- Mount genuine host procfs, not copied directories
- Check /proc/net/dev contents manually when using gVisor/LXC/firecracker
- Upgrade the procfs dependency in the exporter for parser fixes
- Diff actual file headers against the canonical kernel format
When it happens
Trigger: fs.NetDev() errors while scanning/parsing /proc/net/dev: file missing under the mounted procfs, malformed lines (custom kernels, virtualized /proc shims), or read errors mid-parse.
Common situations: --path.procfs pointing at a fake/overlay directory that contains a partial /proc copy; LXC/gVisor environments presenting unusual /proc/net/dev contents; procfs library version incompatibility with unusual kernel output.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- interrupts empty
- ZFS / ZFS statistics are not available
- failed to open procfs
- failed to open procfs
- couldn't get buddyinfo
AI-assisted analysis of prometheus/node_exporter@17ddd77c59 (2026-09-07).
Data as JSON: /api/errors/b5fc44f5ae340d6d.
Report an issue: GitHub.
Appendix: source
Thrown at collector/netdev_linux.go:154
"transmit_compressed": stats.TXCompressed,
"receive_nohandler": stats.RXNoHandler,
}
}
return metrics
}
func procNetDevStats(filter *deviceFilter, logger *slog.Logger) (netDevStats, error) {
metrics := netDevStats{}
fs, err := procfs.NewFS(*procPath)
if err != nil {
return metrics, fmt.Errorf("failed to open procfs: %w", err)
}
netDev, err := fs.NetDev()
if err != nil {
return metrics, fmt.Errorf("failed to parse /proc/net/dev: %w", err)
}
for _, stats := range netDev {
name := stats.Name
if filter.ignored(name) {
logger.Debug("Ignoring device", "device", name)
continue
}
metrics[name] = map[string]uint64{
"receive_bytes": stats.RxBytes,
"receive_packets": stats.RxPackets,
"receive_errors": stats.RxErrors,
"receive_dropped": stats.RxDropped,
"receive_fifo": stats.RxFIFO,
"receive_frame": stats.RxFrame,
"receive_compressed": stats.RxCompressed,View on GitHub (pinned to 17ddd77c59)