prometheus/node_exporter · error

couldn't get ue_count for controller/csrow

Error message

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

What it means

Identical to the ce_count failure but for the uncorrectable-error counter: readUintFromFile(<csrow>/ue_count) failed. The collector returns this wrapped error with controller and csrow numbers, aborting the remainder of the EDAC scrape. The underlying OS error is preserved via %w.

Solutions

  1. Confirm the file exists and is readable: `cat /sys/devices/system/edac/mc/mc0/csrow0/ue_count`.
  2. Fix permissions or SELinux/AppArmor policy so the exporter user can read the sysfs attribute.
  3. In containers, bind-mount /sys from the host read-only.
  4. Update kernel/EDAC driver if the attribute is known to be omitted by your driver version.
Defensive patterns

Strategy: validation

Validate before calling

const fs = require('fs');
const f = '/sys/devices/system/edac/mc/mc0/csrow0/ue_count';
if (!fs.existsSync(f)) {
  console.warn('ue_count missing; your EDAC driver may not expose it — disable --collector.edac');
}

Try / catch

try {
  await scrapeNodeExporter();
} catch (e) {
  if (String(e).includes('couldn\'t get ue_count')) {
    alert('ue_count unreadable: check permissions / SELinux on sysfs EDAC attributes');
  } else throw e;
}

Prevention

When it happens

Trigger: readUintFromFile(filepath.Join(csrow, "ue_count")) returns an error during Update (missing file, permission denied, parse failure).

Common situations: EDAC drivers that publish ce_count but not ue_count; SELinux/AppArmor denying read of the attribute; container without host sysfs bind-mounted; non-integer content in ue_count on buggy drivers.

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

Appendix: source

Thrown at collector/edac_linux.go:161

			return err
		}
		for _, csrow := range csrows {
			csrowMatch := edacMemCsrowRE.FindStringSubmatch(csrow)
			if csrowMatch == nil {
				return fmt.Errorf("csrow string didn't match regexp: %s", csrow)
			}
			csrowNumber := csrowMatch[1]

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

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

			channelFiles, err := filepath.Glob(csrow + "/ch*_ce_count")
			if err != nil {
				return err
			}
			for _, chFile := range channelFiles {
				match := edacMemChannelRE.FindStringSubmatch(filepath.Base(chFile))
				if match == nil {
					continue
				}
				channelNumber := match[1]
				label := edacDimmLabel(csrow, channelNumber)

				value, err = readUintFromFile(chFile)
				if err != nil {

View on GitHub (pinned to 17ddd77c59)