prometheus/node_exporter · error
failed to retrieve rapl stats
Error message
failed to retrieve rapl stats: %w
What it means
The RAPL power collector wraps any non-permission error from reading powercap zones (procfs powercap API) with 'failed to retrieve rapl stats'. Missing powercap and permission errors are downgraded to ErrNoData or a debug log, so this error means a genuine failure enumerating or reading the Intel RAPL powercap interface outside those tolerated cases.
Solutions
- Inspect /sys/class/powercap for intact intel-rapl:* entries with readable name/energy_uj files
- If RAPL is unusable on this host, disable the rapl collector instead of scraping it
- Check dmesg for intel_rapl/powercap errors and update the kernel or run on bare metal
- Verify the container runtime is not masking parts of /sys/class/powercap
Example fix
// before (host without usable RAPL) node_exporter --collector.rapl // after node_exporter --collector.rapl=false # or omit --collector.rapl when not using --collector.disable-defaults
Defensive patterns
Strategy: try-catch
Validate before calling
// caller-side pre-check before enabling the collector
if entries, err := os.ReadDir("/sys/class/powercap"); err != nil || len(entries) == 0 {
// RAPL unavailable; do not enable --collector.rapl
} Type guard
func raplAvailable() bool {
_, err := os.Stat("/sys/class/powercap/intel-rapl:0")
return err == nil
} Try / catch
if err := collector.Update(ch); err != nil {
if strings.Contains(err.Error(), "failed to retrieve rapl stats") {
logger.Warn("RAPL unavailable on this host; power metrics skipped", "err", err)
} else {
return err
}
} Prevention
- Only enable the rapl collector on bare metal or hosts that expose /sys/class/powercap
- Check dmesg for intel_rapl initialization errors when provisioning
- Treat missing/permission-denied powercap as expected: the collector already returns ErrNoData for those
When it happens
Trigger: powercap zone initialization returning an error other than os.ErrNotExist/os.ErrPermission during Update, e.g. malformed /sys/class/powercap contents or I/O errors reading energy files.
Common situations: Containers with partial /sys/class/powercap visibility; virtualized hosts exposing a broken powercap tree; kernels with partial or faulty intel_rapl support.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- Could not derive a human-readable chip type for
- failed to open sysfs
- failed to retrieve bcache stats
- failed to open sysfs
- failed to retrieve bcachefs stats
AI-assisted analysis of prometheus/node_exporter@17ddd77c59 (2026-09-07).
Data as JSON: /api/errors/6b5dc922aa97fca5.
Report an issue: GitHub.
Appendix: source
Thrown at collector/rapl_linux.go:82
joulesMetricDesc: joulesMetricDesc,
}
return &collector, nil
}
// Update implements Collector and exposes RAPL related metrics.
func (c *raplCollector) Update(ch chan<- prometheus.Metric) error {
// nil zones are fine when platform doesn't have powercap files present.
zones, err := sysfs.GetRaplZones(c.fs)
if err != nil {
if errors.Is(err, os.ErrNotExist) {
c.logger.Debug("Platform doesn't have powercap files present", "err", err)
return ErrNoData
}
if errors.Is(err, os.ErrPermission) {
c.logger.Debug("Can't access powercap files", "err", err)
return ErrNoData
}
return fmt.Errorf("failed to retrieve rapl stats: %w", err)
}
for _, rz := range zones {
microJoules, err := rz.GetEnergyMicrojoules()
if err != nil {
if errors.Is(err, os.ErrPermission) {
c.logger.Debug("Can't access energy_uj file", "zone", rz, "err", err)
return ErrNoData
}
return err
}
joules := float64(microJoules) / 1000000.0
if *raplZoneLabel {
ch <- c.joulesMetricWithZoneLabel(rz, joules)
} else {
ch <- c.joulesMetric(rz, joules)View on GitHub (pinned to 17ddd77c59)