prometheus/node_exporter · error

failed to open sysfs

Error message

failed to open sysfs: %w

What it means

NewSysctlCollector wraps procfs.NewFS(*procPath); when opening the /proc (sysctl) filesystem fails, the constructor returns this wrapped error and the sysctl collector is not registered. It almost always means the configured --path.procfs root does not exist or is unreadable. The collector is disabled by default, so it only fires when explicitly enabled with a bad path.

Solutions

  1. Fix --path.procfs to point at a valid procfs mount (usually /proc)
  2. Mount /proc into the container/host path the flag points at
  3. Check permissions: the exporter user must be able to stat the directory
  4. Verify with `ls $(your-procfs-path)/sys` that the filesystem is really procfs

Example fix

// before
node_exporter --collector.sysctl --path.procfs=/host/procs
// after
node_exporter --collector.sysctl --path.procfs=/host/proc
Defensive patterns

Strategy: validation

Validate before calling

if _, err := os.Stat(*procPath); err != nil { return fmt.Errorf("procfs path %q unusable: %w", *procPath, err) }

Try / catch

c, err := NewSysctlCollector(logger)
if err != nil {
    logger.Warn("sysctl collector disabled", "err", err)
    c = nil
}

Prevention

When it happens

Trigger: Starting node_exporter with --collector.sysctl enabled while --path.procfs points to a missing, unmounted, or unreadable directory (e.g. wrong container mount, typo like /host/proc when only /proc exists).

Common situations: Running node_exporter in a container without /proc bind-mounted to the host path; typo in --path.procfs flag; procfs not mounted in minimal/chroot 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/e4e7bd2533e9278e. Report an issue: GitHub.

Appendix: source

Thrown at collector/sysctl_linux.go:47

	sysctlIncludeInfo = kingpin.Flag("collector.sysctl.include-info", "Select sysctl metrics to include as info metrics").Strings()

	sysctlInfoDesc = prometheus.NewDesc(prometheus.BuildFQName(namespace, "sysctl", "info"), "sysctl info", []string{"name", "value", "index"}, nil)
)

type sysctlCollector struct {
	fs      procfs.FS
	logger  *slog.Logger
	sysctls []*sysctl
}

func init() {
	registerCollector("sysctl", defaultDisabled, NewSysctlCollector)
}

func NewSysctlCollector(logger *slog.Logger) (Collector, error) {
	fs, err := procfs.NewFS(*procPath)
	if err != nil {
		return nil, fmt.Errorf("failed to open sysfs: %w", err)
	}
	c := &sysctlCollector{
		logger:  logger,
		fs:      fs,
		sysctls: []*sysctl{},
	}

	for _, include := range *sysctlInclude {
		sysctl, err := newSysctl(include, true)
		if err != nil {
			return nil, err
		}
		c.sysctls = append(c.sysctls, sysctl)
	}

	for _, include := range *sysctlIncludeInfo {
		sysctl, err := newSysctl(include, false)
		if err != nil {

View on GitHub (pinned to 17ddd77c59)