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
- Verify the sysfs path: ls -d /sys (or the value passed to --path.sysfs) exists and is a directory.
- If running in a container, mount /sys (e.g. -v /sys:/sys:ro).
- Correct the --path.sysfs flag value to the real sysfs mount point.
- Check the wrapped cause (%w) for permission errors and run with sufficient filesystem access.
- 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
- Always pass an explicit, verified --path.sysfs value in containerized deployments.
- Mount /sys:ro whenever node_exporter runs in a container.
- Smoke-test collector construction at deploy time instead of discovering at scrape time.
- Disable collectors whose backing filesystem is unavailable.
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
- failed to get vulnerabilities
- error obtaining NVMe class info
- Could not derive a human-readable chip type for
- failed to open sysfs
- failed to retrieve bcache stats
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.txtView on GitHub (pinned to 17ddd77c59)