prometheus/node_exporter · error
failed to retrieve pressure stats
Error message
failed to retrieve pressure stats: %w
What it means
node_exporter's pressure (PSI) collector wraps any failure from reading /proc/pressure/* with this message. It is thrown by Update when fs.PSIStats() returns a non-nil error that is NOT syscall.ENOTSUP (ENOTSUP is special-cased to ErrNoData with a hint to add psi=1 to the kernel command line). Any other I/O or parse error while retrieving pressure stall information produces this wrapped error.
Solutions
- Verify /proc/pressure/cpu, /proc/pressure/memory and /proc/pressure/io exist and are readable from the exporter process (ls -l /proc/pressure; cat /proc/pressure/cpu).
- If PSI is disabled, reboot with psi=1 on the kernel command line so the collector gets ENOTSUP -> ErrNoData instead of a hard failure.
- If running in a container, ensure /proc is mounted and not masked for the path /proc/pressure (docker run without --read-only proc masking, or adjust the runtime spec).
- Update the prometheus/procfs dependency and node_exporter to versions supporting your kernel's PSI output format.
- If the collector is unusable in your environment, disable it (--collector.pressure) to silence scrape failures.
Example fix
// before
if err != nil {
if errors.Is(err, fs.ErrNotExist) {
return ErrNoData
}
return fmt.Errorf("failed to retrieve pressure stats: %w", err)
}
// after
if err != nil {
if errors.Is(err, fs.ErrNotExist) || errors.Is(err, syscall.ENOTSUP) {
return ErrNoData // PSI disabled or unavailable: emit nothing, don't fail the scrape
}
return fmt.Errorf("failed to retrieve pressure stats: %w", err)
} Defensive patterns
Strategy: fallback
Validate before calling
// before starting the collector / scraping
for _, r := range []string{"cpu", "memory", "io"} {
b, err := os.ReadFile("/proc/pressure/" + r)
if err != nil {
if errors.Is(err, os.ErrNotExist) {
log.Printf("PSI unavailable for %s: enable with psi=1 kernel cmdline", r)
}
// treat as no-data
}
_ = b
} Try / catch
stats, err := fs.PSIStats("cpu")
if err != nil {
if errors.Is(err, syscall.ENOTSUP) || errors.Is(err, fs.ErrNotExist) {
return ErrNoData // PSI disabled: skip gracefully
}
return fmt.Errorf("failed to retrieve pressure stats: %w", err)
} Prevention
- Boot kernels with psi=1 (or CONFIG_PSI=y default-on kernels) before deploying the pressure collector.
- Pre-flight check /proc/pressure readability in your deployment script.
- Ensure container runtimes do not mask /proc/pressure.
- Treat ErrNoData as an expected, non-alerting condition in dashboards.
When it happens
Trigger: The pressure collector's Update() calls procfs PSIStats for cpu/memory/io/irq resources; the read or parse of /proc/pressure/<resource> fails with an error other than ENOTSUP (e.g. /proc not mounted, permission issue, or unexpected file contents from an unusual kernel).
Common situations: Running in a container or sandbox where /proc/pressure is not exposed (masked by runtime); very old or vendor kernels that expose malformed PSI data; seccomp/AppArmor policies blocking reads; kernels built without CONFIG_PSI but where the read still fails instead of returning ENOTSUP.
Related errors
- failed to open procfs
- failed to open procfs
- unable to retrieve number of allocated threads
- unable to retrieve limit number of threads
- unable to retrieve limit number of maximum pids allowed
AI-assisted analysis of prometheus/node_exporter@17ddd77c59 (2026-09-07).
Data as JSON: /api/errors/6e5e6f29fdcfdc9a.
Report an issue: GitHub.
Appendix: source
Thrown at collector/pressure_linux.go:119
func (c *pressureStatsCollector) Update(ch chan<- prometheus.Metric) error {
foundResources := 0
for _, res := range psiResources {
c.logger.Debug("collecting statistics for resource", "resource", res)
vals, err := c.fs.PSIStatsForResource(res)
if err != nil {
if errors.Is(err, os.ErrNotExist) && res != psiResourceIRQ {
c.logger.Debug("pressure information is unavailable, you need a Linux kernel >= 4.20 and/or CONFIG_PSI enabled for your kernel", "resource", res)
continue
}
if errors.Is(err, os.ErrNotExist) && res == psiResourceIRQ {
c.logger.Debug("IRQ pressure information is unavailable, you need a Linux kernel >= 6.1 and/or CONFIG_PSI enabled for your kernel", "resource", res)
continue
}
if errors.Is(err, syscall.ENOTSUP) {
c.logger.Debug("pressure information is disabled, add psi=1 kernel command line to enable it")
return ErrNoData
}
return fmt.Errorf("failed to retrieve pressure stats: %w", err)
}
// IRQ pressure does not have 'some' data.
// See https://github.com/torvalds/linux/blob/v6.9/include/linux/psi_types.h#L65
if vals.Some == nil && res != psiResourceIRQ {
c.logger.Debug("pressure information returned no 'some' data")
return ErrNoData
}
if vals.Full == nil && res != psiResourceCPU {
c.logger.Debug("pressure information returned no 'full' data")
return ErrNoData
}
switch res {
case psiResourceCPU:
ch <- prometheus.MustNewConstMetric(c.cpu, prometheus.CounterValue, float64(vals.Some.Total)/1000.0/1000.0)
case psiResourceIO:
ch <- prometheus.MustNewConstMetric(c.io, prometheus.CounterValue, float64(vals.Some.Total)/1000.0/1000.0)
ch <- prometheus.MustNewConstMetric(c.ioFull, prometheus.CounterValue, float64(vals.Full.Total)/1000.0/1000.0)
case psiResourceMemory:View on GitHub (pinned to 17ddd77c59)