prometheus/node_exporter · error

failed to get vulnerabilities

Error message

failed to get vulnerabilities: %w

What it means

The cpu_vulnerabilities collector calls sysfs.NewFS then fs.CPUVulnerabilities() to read /sys/devices/system/cpu/vulnerabilities/*. When that procfs/sysfs read or parse fails, Update wraps the underlying error with "failed to get vulnerabilities: %w" so scrape-level failures surface in the scrape error field.

Solutions

  1. Ensure /sys/devices/system/cpu/vulnerabilities exists and is readable by the node_exporter process (ls /sys/devices/system/cpu/vulnerabilities).
  2. When running in a container, mount /sys into the container (e.g. docker run -v /sys:/sys:ro) and check for host-level SELinux/AppArmor denials in audit logs.
  3. Check the wrapped error text (%w chain) for the concrete cause: read/permission errors vs parse errors; upgrade node_exporter/procfs if it is a parsing issue with a newer kernel.
  4. Disable the cpu_vulnerabilities collector (--no-collector.cpu_vulnerabilities) if the metrics are not needed on that host.

Example fix

// before
vulnerabilities, err := fs.CPUVulnerabilities()
if err != nil {
    return fmt.Errorf("failed to get vulnerabilities: %w", err)
}
// after (caller-side guard: check sysfs availability before scraping)
if _, err := os.Stat("/sys/devices/system/cpu/vulnerabilities"); os.IsNotExist(err) {
    // disable or skip the cpu_vulnerabilities collector on this host
}
Defensive patterns

Strategy: try-catch

Validate before calling

if _, err := os.Stat("/sys/devices/system/cpu/vulnerabilities"); err != nil {
    // sysfs vulnerability entries unavailable: expect this collector to fail
}

Try / catch

if err := coll.Update(ch); err != nil {
    var pathErr *fs.PathError
    if errors.As(err, &pathErr) {
        log.Printf("cpu_vulnerabilities unavailable (sysfs): %v", pathErr)
    } else {
        log.Printf("cpu_vulnerabilities update failed: %v", err)
    }
}

Prevention

When it happens

Trigger: Update() on Linux when fs.CPUVulnerabilities() returns an error: sysfs mount unavailable, /sys/devices/system/cpu/vulnerabilities entries unreadable (permission or LSM restrictions), or unexpected content the procfs package cannot parse.

Common situations: Running node_exporter in a container without /sys mounted (or mounted read-only incorrectly); hardened kernels/SELinux denying read of vulnerability files; kernels or rootfs layouts where the vulnerabilities directory is absent; unusual kernel configurations producing unexpected file contents.

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


AI-assisted analysis of prometheus/node_exporter@17ddd77c59 (2026-09-07). Data as JSON: /api/errors/e5dd476116827772. Report an issue: GitHub.

Appendix: source

Thrown at collector/cpu_vulnerabilities_linux.go:55

type cpuVulnerabilitiesCollector struct{}

func init() {
	registerCollector(cpuVulnerabilitiesCollectorSubsystem, defaultDisabled, NewVulnerabilitySysfsCollector)
}

func NewVulnerabilitySysfsCollector(_ *slog.Logger) (Collector, error) {
	return &cpuVulnerabilitiesCollector{}, nil
}

func (v *cpuVulnerabilitiesCollector) Update(ch chan<- prometheus.Metric) error {
	fs, err := sysfs.NewFS(*sysPath)
	if err != nil {
		return fmt.Errorf("failed to open sysfs: %w", err)
	}

	vulnerabilities, err := fs.CPUVulnerabilities()
	if err != nil {
		return fmt.Errorf("failed to get vulnerabilities: %w", err)
	}

	for _, vulnerability := range vulnerabilities {
		ch <- prometheus.MustNewConstMetric(
			vulnerabilityDesc,
			prometheus.GaugeValue,
			1.0,
			vulnerability.CodeName,
			sysfs.VulnerabilityHumanEncoding[vulnerability.State],
			vulnerability.Mitigation,
		)
	}
	return nil
}

View on GitHub (pinned to 17ddd77c59)