prometheus/node_exporter · error

couldn't get ue_count for controller

Error message

couldn't get ue_count for controller %s: %w

What it means

Same read pattern as the previous counters, applied to ue_count (uncorrectable errors). readUintFromFile failed for a controller directory, aborting the scrape with this wrapped error naming the controller number.

Solutions

  1. Check cat /sys/devices/system/edac/memctlr/mcN/ue_count works for the exporter user
  2. Run node_exporter with adequate privileges
  3. Examine the wrapped (%w) error for the concrete errno or parse failure
  4. Confirm the EDAC driver supports uncorrectable-error accounting; otherwise the collector cannot function for that controller
Defensive patterns

Strategy: validation

Validate before calling

if _, err := os.ReadFile("/sys/devices/system/edac/memctlr/mc0/ue_count"); err != nil {
    // ue_count unreadable; fix permissions or driver support
}

Try / catch

if err := c.Update(ch); err != nil {
    if strings.Contains(err.Error(), "couldn't get ue_count") {
        // check wrapped errno; ENOENT means driver lacks the counter
    }
}

Prevention

When it happens

Trigger: readUintFromFile(<controller>/ue_count) fails: attribute absent for the EDAC driver, read permission denied, or content not parseable as a uint.

Common situations: Drivers that don't populate ue_count; hardened/container environments blocking sysfs reads; kernel layout changes for EDAC uncorrectable-error counters.

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/cc0dcb27dfcd1806. Report an issue: GitHub.

Appendix: source

Thrown at collector/edac_linux.go:128

		controllerNumber := controllerMatch[1]

		value, err := readUintFromFile(filepath.Join(controller, "ce_count"))
		if err != nil {
			return fmt.Errorf("couldn't get ce_count for controller %s: %w", controllerNumber, err)
		}
		ch <- prometheus.MustNewConstMetric(
			edacCeCount, prometheus.CounterValue, float64(value), controllerNumber)

		value, err = readUintFromFile(filepath.Join(controller, "ce_noinfo_count"))
		if err != nil {
			return fmt.Errorf("couldn't get ce_noinfo_count for controller %s: %w", controllerNumber, err)
		}
		ch <- prometheus.MustNewConstMetric(
			edacCsRowCECount, prometheus.CounterValue, float64(value), controllerNumber, "unknown")

		value, err = readUintFromFile(filepath.Join(controller, "ue_count"))
		if err != nil {
			return fmt.Errorf("couldn't get ue_count for controller %s: %w", controllerNumber, err)
		}
		ch <- prometheus.MustNewConstMetric(
			edacUeCount, prometheus.CounterValue, float64(value), controllerNumber)

		value, err = readUintFromFile(filepath.Join(controller, "ue_noinfo_count"))
		if err != nil {
			return fmt.Errorf("couldn't get ue_noinfo_count for controller %s: %w", controllerNumber, err)
		}
		ch <- prometheus.MustNewConstMetric(
			edacCsRowUECount, prometheus.CounterValue, float64(value), controllerNumber, "unknown")

		// For each controller, walk the csrow directories.
		csrows, err := filepath.Glob(controller + "/csrow[0-9]*")
		if err != nil {
			return err
		}
		for _, csrow := range csrows {
			csrowMatch := edacMemCsrowRE.FindStringSubmatch(csrow)

View on GitHub (pinned to 17ddd77c59)