prometheus/node_exporter · error

failed to open sysfs

Error message

failed to open sysfs: %w

What it means

NewCPUFreqCollector builds the collector by opening the sysfs filesystem via sysfs.NewFS(*sysPath) (default /sys). If the sysfs root cannot be opened/validated, construction fails and the error is wrapped as "failed to open sysfs: %w", so the cpufreq collector is never registered.

Solutions

  1. Verify the sysfs path: ls -d /sys (or the value passed to --path.sysfs) exists and is a directory.
  2. If running in a container, mount /sys (e.g. -v /sys:/sys:ro).
  3. Correct the --path.sysfs flag value to the real sysfs mount point.
  4. Check the wrapped cause (%w) for permission errors and run with sufficient filesystem access.
  5. Exclude the cpufreq collector (--no-collector.cpufreq) if frequency metrics are not needed.

Example fix

// before
node_exporter --path.sysfs=/wrong/sys
// after
node_exporter --path.sysfs=/sys
Defensive patterns

Strategy: validation

Validate before calling

if fi, err := os.Stat(sysPath); err != nil || !fi.IsDir() {
    // bad --path.sysfs; fix the flag before starting the collector
}

Try / catch

if _, err := NewCPUFreqCollector(logger); err != nil {
    var perr *fs.PathError
    if errors.As(err, &perr) {
        log.Fatalf("sysfs path invalid: %v", perr)
    }
    log.Fatalf("cpufreq init failed: %v", err)
}

Prevention

When it happens

Trigger: Calling NewCPUFreqCollector (directly or via node_exporter startup with --collector.cpufreq) when sysfs.NewFS fails: the --path.sysfs flag points to a nonexistent or non-directory path, or an fs.Stat/permission error occurs while validating the mount.

Common situations: Typo or wrong value for --path.sysfs; running inside a container without /sys mounted; running node_exporter on a system where /sys is restricted; unit tests passing a bad sysPath fixture path.

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/415bdc9fd8214b49. Report an issue: GitHub.

Appendix: source

Thrown at collector/cpufreq_linux.go:41

	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/procfs/sysfs"
)

type cpuFreqCollector struct {
	fs     sysfs.FS
	descs  cpuFreqDescs
	logger *slog.Logger
}

func init() {
	registerCollector("cpufreq", defaultEnabled, NewCPUFreqCollector)
}

// NewCPUFreqCollector returns a new Collector exposing kernel/system statistics.
func NewCPUFreqCollector(logger *slog.Logger) (Collector, error) {
	fs, err := sysfs.NewFS(*sysPath)
	if err != nil {
		return nil, fmt.Errorf("failed to open sysfs: %w", err)
	}

	return &cpuFreqCollector{
		fs:     fs,
		descs:  newCPUFreqDescs(),
		logger: logger,
	}, nil
}

// Update implements Collector and exposes cpu related metrics from /proc/stat and /sys/.../cpu/.
func (c *cpuFreqCollector) Update(ch chan<- prometheus.Metric) error {
	cpuFreqs, err := c.fs.SystemCpufreq()
	if err != nil {
		return err
	}

	// sysfs cpufreq values are kHz, thus multiply by 1000 to export base units (hz).
	// See https://www.kernel.org/doc/Documentation/cpu-freq/user-guide.txt

View on GitHub (pinned to 17ddd77c59)