prometheus/node_exporter · error

controller string didn't match regexp

Error message

controller string didn't match regexp: %s

What it means

The EDAC collector globs /sys/devices/system/edac/memctlr/mc[0-9]* (via the memControllers list) and expects each controller directory string to match edacMemControllerRE. When a controller entry does not match the expected 'mc<N>' naming, Update aborts with this error. It is an internal-format assumption violated by unexpected sysfs content.

Solutions

  1. Inspect the controller path printed in the error and compare with the expected mc<N> pattern
  2. Identify the EDAC driver creating the oddly named directory and check kernel docs for its layout
  3. Update node_exporter or file an issue if a new kernel layout is not matched
  4. Exclude the offending environment (disable the edac collector) if the layout is unsupported
Defensive patterns

Strategy: validation

Validate before calling

matches, _ := filepath.Glob("/sys/devices/system/edac/memctlr/mc[0-9]*")
re := regexp.MustCompile(`^mc([0-9]+)$`)
for _, m := range matches {
    if !re.MatchString(filepath.Base(m)) {
        // unexpected EDAC controller naming; edac collector Update will fail
    }
}

Try / catch

if err := c.Update(ch); err != nil {
    var prefix = "controller string didn't match regexp"
    if strings.HasPrefix(err.Error(), prefix) {
        // unsupported EDAC layout; disable collector or upgrade node_exporter
    }
}

Prevention

When it happens

Trigger: A directory under the EDAC memctlr path matching the glob but not the regexp, e.g. mcX, mc-0, or an unusual controller name produced by a nonstandard kernel/EDAC driver.

Common situations: Kernels with EDAC drivers that name controllers differently; leftover or synthetic directories in a test fixture or chrooted /sys; kernel version changes altering the EDAC sysfs layout.

Understand the failure class

Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.

Related errors


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

Appendix: source

Thrown at collector/edac_linux.go:108

	if err != nil {
		return label
	}
	label = strings.TrimSpace(string(labelBytes))
	label = strings.ReplaceAll(label, "#", "")
	label = strings.ReplaceAll(label, "csrow", "_csrow")
	label = strings.ReplaceAll(label, "channel", "_channel")
	return label
}

func (c *edacCollector) Update(ch chan<- prometheus.Metric) error {
	memControllers, err := filepath.Glob(sysFilePath("devices/system/edac/mc/mc[0-9]*"))
	if err != nil {
		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"))

View on GitHub (pinned to 17ddd77c59)