prometheus/node_exporter · error
failed to open sysfs
Error message
failed to open sysfs: %w
What it means
NewCPUCollector opens a sysfs handle at --path.sysfs (needed e.g. for CPU frequency and isolated-CPU info) and returns this wrapped error if that filesystem cannot be opened. Like the procfs failure it aborts collector construction at startup.
Solutions
- Mount /sys (read-only) into the container or set --path.sysfs to the correct location
- Verify the target directory is a real sysfs mount and readable
- Run the platform-correct exporter binary if not on Linux
Example fix
// before docker run node_exporter # no /sys mounted // after docker run -v /sys:/host/sys:ro node_exporter --path.sysfs=/host/sys
Defensive patterns
Strategy: validation
Validate before calling
// Go: pre-flight sysfs availability
if fi, err := os.Stat(filepath.Join(*sysPath, "devices/system/cpu")); err != nil || !fi.IsDir() {
return fmt.Errorf("--path.sysfs %q lacks /sys/devices/system/cpu", *sysPath)
} Try / catch
if _, err := NewCPUCollector(logger); err != nil {
if strings.Contains(err.Error(), "failed to open sysfs") {
return fmt.Errorf("fix --path.sysfs (default /sys): %w", err)
}
return err
} Prevention
- Bind-mount /sys read-only in containers alongside --path.sysfs=/host/sys
- Confirm the mount namespace of the exporter can see /sys
- Test collector startup flags on a staging host
When it happens
Trigger: sysfs.NewFS(*sysPath) errors: --path.sysfs does not exist, is not sysfs, or is unreadable.
Common situations: Containers that do not mount /sys (or mount it elsewhere, e.g. /host/sys) without adjusting --path.sysfs; running the Linux exporter build outside Linux; restrictive mount namespaces.
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 sysfs
- Could not derive a human-readable chip type for
- failed to open sysfs
- failed to retrieve bcache stats
- failed to open sysfs
AI-assisted analysis of prometheus/node_exporter@17ddd77c59 (2026-09-07).
Data as JSON: /api/errors/da8032c4a254b1e8.
Report an issue: GitHub.
Appendix: source
Thrown at collector/cpu_linux.go:82
flagsInclude = kingpin.Flag("collector.cpu.info.flags-include", "Filter the `flags` field in cpuInfo with a value that must be a regular expression").String()
bugsInclude = kingpin.Flag("collector.cpu.info.bugs-include", "Filter the `bugs` field in cpuInfo with a value that must be a regular expression").String()
jumpBackDebugMessage = fmt.Sprintf("CPU Idle counter jumped backwards more than %f seconds, possible hotplug event, resetting CPU stats", jumpBackSeconds)
)
func init() {
registerCollector("cpu", defaultEnabled, NewCPUCollector)
}
// NewCPUCollector returns a new Collector exposing kernel/system statistics.
func NewCPUCollector(logger *slog.Logger) (Collector, error) {
pfs, err := procfs.NewFS(*procPath)
if err != nil {
return nil, fmt.Errorf("failed to open procfs: %w", err)
}
sfs, err := sysfs.NewFS(*sysPath)
if err != nil {
return nil, fmt.Errorf("failed to open sysfs: %w", err)
}
isolcpus, err := sfs.IsolatedCPUs()
if err != nil {
if !os.IsNotExist(err) {
return nil, fmt.Errorf("unable to get isolated cpus: %w", err)
}
logger.Debug("couldn't open isolated file", "error", err)
}
c := &cpuCollector{
procfs: pfs,
sysfs: sfs,
cpu: nodeCPUSecondsDesc,
cpuInfo: prometheus.NewDesc(
prometheus.BuildFQName(namespace, cpuCollectorSubsystem, "info"),
"CPU information from /proc/cpuinfo.",
[]string{"package", "core", "cpu", "vendor", "family", "model", "model_name", "microcode", "stepping", "cachesize"}, nil,View on GitHub (pinned to 17ddd77c59)