prometheus/node_exporter · error

failed to retrieve nfsd stats

Error message

failed to retrieve nfsd stats: %w

What it means

The nfsd collector's Update calls fs.ServerRPCStats() to read /proc/net/rpc/nfsd server statistics through the procfs library. Failures other than os.ErrNotExist (which is treated as 'nfsd not present' and returns ErrNoData) are wrapped in this message. It indicates the nfsd stats file could not be read or parsed even though the procfs mount itself is valid.

Solutions

  1. Read the wrapped cause (%w) to identify whether it is permission, I/O, or parse related.
  2. Confirm readability as the exporter's user: 'cat /proc/net/rpc/nfsd'.
  3. Adjust container/LSM policy so /proc/net/rpc/nfsd is readable, or mount host /proc with the rpc subtree exposed.
  4. On parse errors with newer kernels, upgrade node_exporter/procfs.
  5. If the host genuinely has no nfsd, expect ErrNoData instead; this error means the file exists but is unreadable.

Example fix

// before: SELinux denies read of /proc/net/rpc/nfsd
// after: allow the exporter domain to read proc_net_rpc
//   setsebool -P daemons_dump_core off  # example audit2allow flow:
//   audit2allow -a -M node_exporter-proc-rpc && semodule -i node_exporter-proc-rpc.pp
Defensive patterns

Strategy: try-catch

Validate before calling

// Go: precheck nfsd stats readability
if f, err := os.Open(filepath.Join(*procPath, "net/rpc/nfsd")); err != nil {
    log.Printf("nfsd stats not readable: %v", err)
} else {
    f.Close()
}

Try / catch

// same pattern as nfs collector: skip not-exist, wrap the rest
if errors.Is(err, os.ErrNotExist) {
    return ErrNoData
}
return fmt.Errorf("failed to retrieve nfsd stats: %w", err)

Prevention

When it happens

Trigger: c.fs.ServerRPCStats() returns a non-ErrNotExist error: permission denied on /proc/net/rpc/nfsd, truncated or malformed stats content that procfs cannot parse, or an I/O error while reading the file.

Common situations: Enabling --collector.nfsd on hosts where the nfsd kernel module is loaded partially or /proc/net/rpc/nfsd is restricted by security policy; containers where only parts of /proc/net/rpc are exposed; kernel version whose nfsd stats format is not supported by the bundled procfs version.

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


AI-assisted analysis of prometheus/node_exporter@17ddd77c59 (2026-09-07). Data as JSON: /api/errors/6533f9dbfe580891. Report an issue: GitHub.

Appendix: source

Thrown at collector/nfsd_linux.go:70

		fs: fs,
		requestsDesc: prometheus.NewDesc(
			prometheus.BuildFQName(namespace, nfsdSubsystem, "requests_total"),
			"Total number NFSd Requests by method and protocol.",
			[]string{"proto", "method"}, nil,
		),
		logger: logger,
	}, nil
}

// Update implements Collector.
func (c *nfsdCollector) Update(ch chan<- prometheus.Metric) error {
	stats, err := c.fs.ServerRPCStats()
	if err != nil {
		if errors.Is(err, os.ErrNotExist) {
			c.logger.Debug("Not collecting NFSd metrics", "err", err)
			return ErrNoData
		}
		return fmt.Errorf("failed to retrieve nfsd stats: %w", err)
	}

	c.updateNFSdReplyCacheStats(ch, &stats.ReplyCache)
	c.updateNFSdFileHandlesStats(ch, &stats.FileHandles)
	c.updateNFSdInputOutputStats(ch, &stats.InputOutput)
	c.updateNFSdThreadsStats(ch, &stats.Threads)
	c.updateNFSdReadAheadCacheStats(ch, &stats.ReadAheadCache)
	c.updateNFSdNetworkStats(ch, &stats.Network)
	c.updateNFSdServerRPCStats(ch, &stats.ServerRPC)
	c.updateNFSdRequestsv2Stats(ch, &stats.V2Stats)
	c.updateNFSdRequestsv3Stats(ch, &stats.V3Stats)
	c.updateNFSdRequestsv4Stats(ch, &stats.V4Ops)
	ch <- prometheus.MustNewConstMetric(c.requestsDesc, prometheus.CounterValue,
		float64(stats.WdelegGetattr), "4", "WdelegGetattr")

	return nil
}

View on GitHub (pinned to 17ddd77c59)