{"record":{"id":"faa7542f5ad316b2","repo":"prometheus/node_exporter","slug":"csrow-string-didn-t-match-regexp-s","errorCode":null,"errorMessage":"csrow string didn't match regexp: %s","messagePattern":"csrow string didn't match regexp: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"collector/edac_linux.go","lineNumber":148,"sourceCode":"\t\tch <- prometheus.MustNewConstMetric(\n\t\t\tedacUeCount, prometheus.CounterValue, float64(value), controllerNumber)\n\n\t\tvalue, err = readUintFromFile(filepath.Join(controller, \"ue_noinfo_count\"))\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"couldn't get ue_noinfo_count for controller %s: %w\", controllerNumber, err)\n\t\t}\n\t\tch <- prometheus.MustNewConstMetric(\n\t\t\tedacCsRowUECount, prometheus.CounterValue, float64(value), controllerNumber, \"unknown\")\n\n\t\t// For each controller, walk the csrow directories.\n\t\tcsrows, err := filepath.Glob(controller + \"/csrow[0-9]*\")\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tfor _, csrow := range csrows {\n\t\t\tcsrowMatch := edacMemCsrowRE.FindStringSubmatch(csrow)\n\t\t\tif csrowMatch == nil {\n\t\t\t\treturn fmt.Errorf(\"csrow string didn't match regexp: %s\", csrow)\n\t\t\t}\n\t\t\tcsrowNumber := csrowMatch[1]\n\n\t\t\tvalue, err = readUintFromFile(filepath.Join(csrow, \"ce_count\"))\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"couldn't get ce_count for controller/csrow %s/%s: %w\", controllerNumber, csrowNumber, err)\n\t\t\t}\n\t\t\tch <- prometheus.MustNewConstMetric(\n\t\t\t\tedacCsRowCECount, prometheus.CounterValue, float64(value), controllerNumber, csrowNumber)\n\n\t\t\tvalue, err = readUintFromFile(filepath.Join(csrow, \"ue_count\"))\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"couldn't get ue_count for controller/csrow %s/%s: %w\", controllerNumber, csrowNumber, err)\n\t\t\t}\n\t\t\tch <- prometheus.MustNewConstMetric(\n\t\t\t\tedacCsRowUECount, prometheus.CounterValue, float64(value), controllerNumber, csrowNumber)\n\n\t\t\tchannelFiles, err := filepath.Glob(csrow + \"/ch*_ce_count\")","sourceCodeStart":130,"sourceCodeEnd":166,"githubUrl":"https://github.com/prometheus/node_exporter/blob/17ddd77c59ba27e1508e9f7894b1e55b44d6aed3/collector/edac_linux.go#L130-L166","documentation":"The EDAC collector globs /sys/devices/system/edac/mc/mc*/csrow* directories and parses each path with edacMemCsrowRE to extract the csrow number. When a matched path's basename does not match the expected regexp, Update returns this error and the whole collector scrape fails. It indicates an unexpected sysfs layout rather than bad user input.","triggerScenarios":"filepath.Glob returns a path (e.g. mc0/csrow0 or an unexpected file) whose basename fails to match edacMemCsrowRE during Collector.Update.","commonSituations":"Custom or non-standard EDAC kernel drivers exposing unusual entries under the mc/ directory; kernel versions with different csrow layout; leftover entries created by loaded-but-broken EDAC modules; test fixtures with malformed csrow names.","solutions":["Check `ls /sys/devices/system/edac/mc/mc*/` for entries that do not look like csrowN and identify the driver creating them.","Unload or update the offending EDAC kernel module, or use a kernel whose EDAC layout matches the collector's regexp.","Verify the collector version matches your kernel generation (newer kernels replaced csrow with dimm/* layout, handled by a different code path).","If a legitimate new layout is found, file/patch upstream to extend edacMemCsrowRE."],"exampleFix":"// before: regexp assumes only csrowN basenames\nvar edacMemCsrowRE = regexp.MustCompile(`csrow([0-9]*)`)\n\n// after: skip-but-log unmatched entries instead of failing the scrape\nif csrowMatch == nil {\n\tlogger.Debug(\"skipping unmatched csrow entry\", \"path\", csrow)\n\tcontinue\n}","handlingStrategy":"validation","validationCode":"const cmd = require('child_process').execSync;\nconst csrows = cmd(\"ls -d /sys/devices/system/edac/mc/mc*/csrow* 2>/dev/null || true\").toString().trim();\nif (csrows) {\n  const bad = csrows.split('\\n').filter(p => !/csrow\\d+$/.test(p));\n  if (bad.length) console.warn('Unrecognized EDAC entries, edac collector may fail:', bad);\n}","typeGuard":"function isCsrowPath(p) { return /csrow\\d+$/.test(p); }","tryCatchPattern":null,"preventionTips":["Keep kernel and EDAC drivers vendor-supported and up to date.","Audit /sys/devices/system/edac/mc/ contents after loading EDAC modules.","Pin node_exporter version appropriate for your kernel generation (csrow vs dimm layout)."],"tags":["linux","edac","sysfs","memory-error-reporting"],"backgroundTag":"internal-invariant-violation","analyzedSha":"17ddd77c59ba27e1508e9f7894b1e55b44d6aed3","analyzedAt":"2026-09-07T17:54:06.211Z","contentChangedAt":"2026-09-07T17:54:06.211Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}