prometheus/node_exporter · error
failed to open procfs
Error message
failed to open procfs: %w
What it means
NewProcessStatCollector initializes a procfs filesystem handle via procfs.NewFS(*procPath) and fails the collector constructor when that call errors. This means the proc filesystem could not be opened at the configured path (default /proc), so the process collector cannot be created at all.
Solutions
- Check that /proc (or the value of --path.procfs) exists and is a mounted proc filesystem: mount | grep proc.
- Fix the --path.procfs flag if it was set incorrectly; the default should be /proc.
- In containers, run with /proc mounted (default on Docker/Kubernetes) and avoid masking the whole proc mount.
- When running tests, unpack the fixtures (make test unpacks collector/fixtures/sys.ttar) and point --path.procfs at collector/fixtures/sys.
Example fix
// before node_exporter --path.procfs=/prco // after node_exporter --path.procfs=/proc
Defensive patterns
Strategy: validation
Validate before calling
// before launching the exporter / constructing the collector
func procfsAvailable(path string) error {
var st syscall.Statfs_t
if err := syscall.Statfs(path, &st); err != nil {
return err
}
if st.Type != 0x9fa0 { // PROC_SUPER_MAGIC
return fmt.Errorf("%s is not a procfs mount", path)
}
return nil
} Try / catch
collector, err := NewProcessStatCollector(logger)
if err != nil {
log.Fatalf("process collector unavailable: %v (is %s a mounted procfs?)", err, *procPath)
} Prevention
- Never override --path.procfs unless running tests against fixtures.
- In containers, confirm /proc is mounted and not fully masked.
- Validate the procfs path exists and is procfs in your systemd unit/entrypoint.
- For tests, run make test to unpack fixtures before pointing procfs at them.
When it happens
Trigger: procfs.NewFS is called with the --path.procfs flag value and returns an error, e.g. when the procfs mount point does not exist or statfs on it fails during collector construction at exporter startup.
Common situations: Running node_exporter on non-Linux setups or in containers where /proc is not mounted; passing --path.procfs pointing to a extracted fixture directory that was deleted; typos in --path.procfs such as --path.procfs=/prco.
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 procfs
- failed to retrieve pressure stats
AI-assisted analysis of prometheus/node_exporter@17ddd77c59 (2026-09-07).
Data as JSON: /api/errors/abe57e27fe6afda9.
Report an issue: GitHub.
Appendix: source
Thrown at collector/processes_linux.go:51
fs procfs.FS
threadAlloc *prometheus.Desc
threadLimit *prometheus.Desc
threadsState *prometheus.Desc
procsState *prometheus.Desc
pidUsed *prometheus.Desc
pidMax *prometheus.Desc
logger *slog.Logger
}
func init() {
registerCollector("processes", defaultDisabled, NewProcessStatCollector)
}
// NewProcessStatCollector returns a new Collector exposing process data read from the proc filesystem.
func NewProcessStatCollector(logger *slog.Logger) (Collector, error) {
fs, err := procfs.NewFS(*procPath)
if err != nil {
return nil, fmt.Errorf("failed to open procfs: %w", err)
}
subsystem := "processes"
return &processCollector{
fs: fs,
threadAlloc: prometheus.NewDesc(
prometheus.BuildFQName(namespace, subsystem, "threads"),
"Allocated threads in system",
nil, nil,
),
threadLimit: prometheus.NewDesc(
prometheus.BuildFQName(namespace, subsystem, "max_threads"),
"Limit of threads in the system",
nil, nil,
),
threadsState: prometheus.NewDesc(
prometheus.BuildFQName(namespace, subsystem, "threads_state"),
"Number of threads in each state.",
[]string{"thread_state"}, nil,View on GitHub (pinned to 17ddd77c59)