prometheus/node_exporter · error

failed to open procfs

Error message

failed to open procfs: %w

What it means

NewCgroupSummaryCollector wraps errors from procfs.NewFS(*procPath) in "failed to open procfs". The collector could not obtain a procfs handle at construction time, so no cgroup summary metrics can be collected. Same root causes as other procfs-opening collectors: /proc missing, misconfigured path, or access denied.

Solutions

  1. Ensure /proc is mounted and readable, and --path.procfs is correct if overridden
  2. Relax hidepid or run the exporter with sufficient privileges if /proc access is restricted
  3. Disable the cgroups collector (--no-collector.cgroups) in environments without procfs
  4. Inspect LSM/seccomp logs for denials on /proc

Example fix

// before
 collector, err := NewNodeCollector(logger, "cgroups")
// after
 if fi, err := os.Stat(*procPath); err != nil || !fi.IsDir() {
	logger.Warn("procfs path invalid; skipping cgroups collector")
	return nil
 }
 collector, err = NewNodeCollector(logger, "cgroups")
Defensive patterns

Strategy: fallback

Validate before calling

if fi, err := os.Stat(*procPath); err != nil || !fi.IsDir() { /* skip cgroups collector */ }

Type guard

func procfsReady(path string) bool { fi, err := os.Stat(path); return err == nil && fi.IsDir() }

Try / catch

c, err := collector.NewNodeCollector(logger)
if err != nil {
	logger.Warn("cgroups collector unavailable", "err", err)
	c = nil
}

Prevention

When it happens

Trigger: Enabling the cgroups collector where /proc is not mounted, --path.procfs points to an invalid directory, the process lacks permission to access /proc, or in restricted container namespaces.

Common situations: Containers without procfs mounted; unit/integration tests using a bogus procPath; hosts with procfs hidepid settings that restrict access; non-Linux environments.

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


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

Appendix: source

Thrown at collector/cgroups_linux.go:54

var (
	cgroupsCgroups = prometheus.NewDesc(
		prometheus.BuildFQName(namespace, cgroupsCollectorSubsystem, "cgroups"),
		"Current cgroup number of the subsystem.",
		[]string{"subsys_name"}, nil,
	)
	cgroupsEnabled = prometheus.NewDesc(
		prometheus.BuildFQName(namespace, cgroupsCollectorSubsystem, "enabled"),
		"Current cgroup number of the subsystem.",
		[]string{"subsys_name"}, nil,
	)
)

// NewCgroupSummaryCollector returns a new Collector exposing a summary of cgroups.
func NewCgroupSummaryCollector(logger *slog.Logger) (Collector, error) {
	fs, err := procfs.NewFS(*procPath)
	if err != nil {
		return nil, fmt.Errorf("failed to open procfs: %w", err)
	}
	return &cgroupSummaryCollector{
		fs:     fs,
		logger: logger,
	}, nil
}

// Update implements Collector and exposes cgroup statistics.
func (c *cgroupSummaryCollector) Update(ch chan<- prometheus.Metric) error {
	cgroupSummarys, err := c.fs.CgroupSummarys()
	if err != nil {
		return err
	}
	for _, cs := range cgroupSummarys {
		ch <- prometheus.MustNewConstMetric(cgroupsCgroups, prometheus.GaugeValue, float64(cs.Cgroups), cs.SubsysName)
		ch <- prometheus.MustNewConstMetric(cgroupsEnabled, prometheus.GaugeValue, float64(cs.Enabled), cs.SubsysName)
	}
	return nil

View on GitHub (pinned to 17ddd77c59)