prometheus/node_exporter · error

couldn't get ce_noinfo_count for controller

Error message

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

What it means

Identical pattern to ce_count but for the ce_noinfo_count attribute: readUintFromFile failed while scraping a memory controller, so Update returns this wrapped error. It means correctable errors without DIMM info could not be read for that controller.

Solutions

  1. Verify /sys/devices/system/edac/memctlr/mcN/ce_noinfo_count exists and is readable
  2. Run with sufficient privileges (root or relaxed sysfs permissions)
  3. Read the wrapped cause to identify ENOENT vs EACCES vs parse failure
  4. If the driver never exposes this counter, disable the edac collector or patch it to tolerate the missing attribute
Defensive patterns

Strategy: validation

Validate before calling

if _, err := os.ReadFile("/sys/devices/system/edac/memctlr/mc0/ce_noinfo_count"); err != nil {
    // attribute missing or unreadable; expect scrape failure
}

Try / catch

if err := c.Update(ch); err != nil {
    if strings.Contains(err.Error(), "couldn't get ce_noinfo_count") {
        // driver may not expose this counter; disable edac collector or fix permissions
    }
}

Prevention

When it happens

Trigger: readUintFromFile(<controller>/ce_noinfo_count) returns an error: file missing (driver doesn't expose it), permission denied, or unparseable content.

Common situations: Older or specialized EDAC drivers lacking ce_noinfo_count; permission-restricted sysfs in containers; partially populated EDAC directories after driver reload.

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

Appendix: source

Thrown at collector/edac_linux.go:121

		return err
	}
	for _, controller := range memControllers {
		controllerMatch := edacMemControllerRE.FindStringSubmatch(controller)
		if controllerMatch == nil {
			return fmt.Errorf("controller string didn't match regexp: %s", controller)
		}
		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")

View on GitHub (pinned to 17ddd77c59)