prometheus/node_exporter · error
failed to open procfs
Error message
failed to open procfs: %w
What it means
NewNFSdCollector constructs the collector by calling nfs.NewFS(*procPath), which validates that the given procfs mount point exists and looks like a proc filesystem. If it cannot be opened (missing path, wrong path flag, or not a procfs mount), the constructor returns this wrapped error and no collector is created. This is a startup-time failure, not a scrape-time one.
Solutions
- Pass the correct procfs location: --path.procfs=/proc (or the mounted host path in containers).
- Verify the directory exists and is a procfs mount: 'mount | grep proc' and 'ls /proc/net/rpc/nfsd'.
- In containers, mount the host proc read-only, e.g. -v /proc:/host/proc:ro, and point --path.procfs at it.
- Check the wrapped cause in the error to distinguish ENOENT (wrong path) from other failures.
Example fix
// before: wrong proc path inside container // ./node_exporter --collector.nfsd // after: mount and point at host procfs // docker run -v /proc:/host/proc:ro node-exporter \ // --path.procfs=/host/proc --collector.nfsd
Defensive patterns
Strategy: validation
Validate before calling
// Go: validate proc path before constructing the collector
st, err := os.Stat(filepath.Join(*procPath, "net/rpc/nfsd"))
if err != nil || st.IsDir() {
log.Fatalf("invalid --path.procfs (%s): nfsd stats unavailable", *procPath)
} Try / catch
// constructor errors are fatal at startup; check and fail fast
fs, err := nfs.NewFS(*procPath)
if err != nil {
return nil, fmt.Errorf("failed to open procfs: %w", err) // surface wrapped cause
} Prevention
- Always confirm /proc/net/rpc/nfsd exists in the environment where you enable --collector.nfsd.
- In containers, mount host /proc ro and set --path.procfs=/host/proc from day one.
- Avoid overriding --path.procfs unless you know the mounted location.
- Smoke-test new container images with the exact collector flags before rollout.
When it happens
Trigger: Calling NewNFSdCollector (directly or via node_exporter startup) when the --path.procfs flag points to a nonexistent directory or a directory that is not a procfs mount, causing nfs.NewFS to fail.
Common situations: Running node_exporter in a container without mounting the host /proc and forgetting --path.procfs=/host/proc; typo in --path.procfs; running on a system where the proc path was overridden for testing to an invalid value.
Understand the failure class
Background: "open() failed", "failed to open file", "cannot create file" — what a file open error means and how to fix it — this error's family across 42 libraries.
Related errors
- failed to open procfs
- failed to open procfs
- failed to open procfs
- failed to open sysfs
- failed to retrieve nfsd stats
AI-assisted analysis of prometheus/node_exporter@17ddd77c59 (2026-09-07).
Data as JSON: /api/errors/2d9e8757939acab1.
Report an issue: GitHub.
Appendix: source
Thrown at collector/nfsd_linux.go:48
type nfsdCollector struct {
fs nfs.FS
requestsDesc *prometheus.Desc
logger *slog.Logger
}
func init() {
registerCollector("nfsd", defaultEnabled, NewNFSdCollector)
}
const (
nfsdSubsystem = "nfsd"
)
// NewNFSdCollector returns a new Collector exposing /proc/net/rpc/nfsd statistics.
func NewNFSdCollector(logger *slog.Logger) (Collector, error) {
fs, err := nfs.NewFS(*procPath)
if err != nil {
return nil, fmt.Errorf("failed to open procfs: %w", err)
}
return &nfsdCollector{
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) {View on GitHub (pinned to 17ddd77c59)