prometheus/node_exporter · error
failed to open sysfs
Error message
failed to open sysfs: %w
What it means
NewThermalZoneCollector wraps the error returned by sysfs.NewFS when the /sys mount point (path given by --path.sysfs) cannot be opened. sysfs.NewFS fails when the path does not exist or is not a directory, so the collector cannot be constructed at registration time. This is a constructor error, not a scrape-time error.
Solutions
- Verify /sys exists and is a directory on the target host (ls -ld /sys).
- Correct the --path.sysfs flag to point at the real sysfs mount.
- In containers/Kubernetes, mount /sys from the host into the exporter container.
- If the platform has no sysfs, don't enable the thermal_zone collector.
Example fix
// before node_exporter --path.sysfs=/host/wrong-sys // after node_exporter --path.sysfs=/sys # or the correctly mounted host path
Defensive patterns
Strategy: validation
Validate before calling
if fi, err := os.Stat(sysfsPath); err != nil || !fi.IsDir() {
// sysfs unavailable: don't enable the thermal_zone collector
} Try / catch
c, err := collector.NewThermalZoneCollector(logger)
if err != nil {
logger.Warn("thermal_zone collector disabled", "err", err)
} else {
registry.MustRegister(c)
} Prevention
- Validate --path.sysfs exists before enabling sysfs-based collectors.
- Mount /sys in containerized deployments.
- Use default flag values unless you deliberately relocated pseudo-filesystems.
- Register collectors conditionally so one unavailable fs doesn't kill startup.
When it happens
Trigger: Calling NewThermalZoneCollector (node_exporter --collector.thermal_zone) when *sysPath points to a nonexistent or non-directory path, e.g. --path.sysfs=/wrong/path.
Common situations: Running node_exporter in a container where /sys is not mounted, misconfigured --path.sysfs flag in systemd unit files, or host-path remapping under Kubernetes that hides the real /sys.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- failed to open sysfs
- failed to open sysfs
- failed to open sysfs
- failed to open sysfs
- failed to open sysfs
AI-assisted analysis of prometheus/node_exporter@17ddd77c59 (2026-09-07).
Data as JSON: /api/errors/30666aa5ed5f7095.
Report an issue: GitHub.
Appendix: source
Thrown at collector/thermal_zone_linux.go:48
const thermalZone = "thermal_zone"
type thermalZoneCollector struct {
fs sysfs.FS
coolingDeviceCurState *prometheus.Desc
coolingDeviceMaxState *prometheus.Desc
zoneTemp *prometheus.Desc
logger *slog.Logger
}
func init() {
registerCollector("thermal_zone", defaultEnabled, NewThermalZoneCollector)
}
// NewThermalZoneCollector returns a new Collector exposing kernel/system statistics.
func NewThermalZoneCollector(logger *slog.Logger) (Collector, error) {
fs, err := sysfs.NewFS(*sysPath)
if err != nil {
return nil, fmt.Errorf("failed to open sysfs: %w", err)
}
return &thermalZoneCollector{
fs: fs,
zoneTemp: prometheus.NewDesc(
prometheus.BuildFQName(namespace, thermalZone, "temp"),
"Zone temperature in Celsius",
[]string{"zone", "type"}, nil,
),
coolingDeviceCurState: prometheus.NewDesc(
prometheus.BuildFQName(namespace, coolingDevice, "cur_state"),
"Current throttle state of the cooling device",
[]string{"name", "type"}, nil,
),
coolingDeviceMaxState: prometheus.NewDesc(
prometheus.BuildFQName(namespace, coolingDevice, "max_state"),
"Maximum throttle state of the cooling device",
[]string{"name", "type"}, nil,View on GitHub (pinned to 17ddd77c59)