prometheus/node_exporter · error
failed to retrieve nfs stats
Error message
failed to retrieve nfs stats: %w
What it means
The NFS collector's Update calls fs.ClientRPCStats() to read /proc/net/rpc/nfs client RPC statistics via the procfs library. When that read fails with an error other than os.ErrNotExist (the common 'no NFS client' case, which is silently skipped as ErrNoData), the collector wraps the underlying error in this message. It means the /proc file exists but could not be opened, read, or parsed.
Solutions
- Verify node_exporter can read the file: run 'cat /proc/net/rpc/nfs' as the same user the exporter runs as.
- Check container/namespace setup: mount host /proc (e.g. /host/proc via --path.procfs) so the NFS stats file is visible.
- Inspect the wrapped cause (%w) in the log line to determine whether it is a parse error vs an open/permission error.
- If the file is absent on hosts without NFS, treat this as expected behavior; the collector intentionally returns ErrNoData for os.ErrNotExist.
- Update procfs/node_exporter if the cause is a parse failure on a newer kernel's stats format.
Example fix
// before: collector fails every scrape on restricted /proc // after: run exporter with host procfs and read access // docker run -v /proc:/host/proc:ro node-exporter --path.procfs=/host/proc // or in systemd: // [Service] // ReadOnlyPaths=/proc/net/rpc # ensure this is NOT blocking reads
Defensive patterns
Strategy: try-catch
Validate before calling
// Go: check readability before enabling the collector
if f, err := os.Open(filepath.Join(*procPath, "net/rpc/nfs")); err != nil {
log.Printf("nfs stats not readable: %v", err)
} else {
f.Close()
} Try / catch
// treat wrapped error: distinguish not-exist from real failures
if errors.Is(err, os.ErrNotExist) {
return ErrNoData // expected on non-NFS hosts
}
return fmt.Errorf("failed to retrieve nfs stats: %w", err) // log cause, alert on persistence Prevention
- Run node_exporter with read access to /proc/net/rpc (check with sudo -u exporter cat /proc/net/rpc/nfs).
- In containers, mount host /proc read-only and pass --path.procfs.
- Only enable --collector.nfs on hosts that actually use NFS.
- Alert on scrape error metrics rather than treating single failures as fatal.
When it happens
Trigger: c.fs.ClientRPCStats() returns a non-ErrNotExist error: e.g. permission failure reading /proc/net/rpc/nfs, a kernel producing malformed statistics text that procfs cannot parse, or a procfs library error opening the file.
Common situations: Running node_exporter in a container where /proc/net/rpc/nfs is masked or bind-mounted read-only with restricted permissions; unusual/custom kernels emitting unexpected /proc/net/rpc/nfs formatting; hardened LSM policies (SELinux/AppArmor) blocking reads of /proc/net/rpc.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- failed to get vulnerabilities
- couldn't get diskstats
- failed to open procfs
- failed to open procfs
- failed to retrieve nfsd stats
AI-assisted analysis of prometheus/node_exporter@17ddd77c59 (2026-09-07).
Data as JSON: /api/errors/9c6012b0c2545fec.
Report an issue: GitHub.
Appendix: source
Thrown at collector/nfs_linux.go:104
),
nfsProceduresDesc: prometheus.NewDesc(
prometheus.BuildFQName(namespace, nfsSubsystem, "requests_total"),
"Number of NFS procedures invoked.",
[]string{"proto", "method"},
nil,
),
logger: logger,
}, nil
}
func (c *nfsCollector) Update(ch chan<- prometheus.Metric) error {
stats, err := c.fs.ClientRPCStats()
if err != nil {
if errors.Is(err, os.ErrNotExist) {
c.logger.Debug("Not collecting NFS metrics", "err", err)
return ErrNoData
}
return fmt.Errorf("failed to retrieve nfs stats: %w", err)
}
c.updateNFSNetworkStats(ch, &stats.Network)
c.updateNFSClientRPCStats(ch, &stats.ClientRPC)
c.updateNFSRequestsv2Stats(ch, &stats.V2Stats)
c.updateNFSRequestsv3Stats(ch, &stats.V3Stats)
c.updateNFSRequestsv4Stats(ch, &stats.ClientV4Stats)
return nil
}
// updateNFSNetworkStats collects statistics for network packets/connections.
func (c *nfsCollector) updateNFSNetworkStats(ch chan<- prometheus.Metric, s *nfs.Network) {
ch <- prometheus.MustNewConstMetric(c.nfsNetReadsDesc, prometheus.CounterValue,
float64(s.UDPCount), "udp")
ch <- prometheus.MustNewConstMetric(c.nfsNetReadsDesc, prometheus.CounterValue,
float64(s.TCPCount), "tcp")
ch <- prometheus.MustNewConstMetric(c.nfsNetConnectionsDesc, prometheus.CounterValue,View on GitHub (pinned to 17ddd77c59)