prometheus/node_exporter · error
invalid line in meminfo
Error message
invalid line in meminfo: %s
What it means
This error is returned by parseMemInfoNuma in collector/meminfo_numa_linux.go:147 when a line from a per-NUMA-node meminfo file has a field count other than 4 fields (no unit) or 5 fields with 'kB' as the unit. The switch on len(parts) rejects any other shape, so unexpected units (e.g. 'MB', 'GB') or extra/missing columns cause a full parse failure.
Solutions
- Check the failing line in /sys/devices/system/node/node*/meminfo for unexpected unit or column count
- If the kernel emits a new unit (MB/GB), extend the switch to handle it and scale accordingly
- Confirm kernel version; update the collector parser if sysfs format changed upstream
- Rebuild with -tags nomeminfo_numa to skip this collector on unsupported platforms
- Report the format upstream via a GitHub issue with the exact offending line
Example fix
// before
case l == 5 && parts[4] == "kB": // has unit
fv *= 1024
default:
return nil, fmt.Errorf("invalid line in meminfo: %s", line)
// after
case l == 5 && parts[4] == "kB":
fv *= 1024
case l == 5 && parts[4] == "MB":
fv *= 1024 * 1024
default:
return nil, fmt.Errorf("invalid line in meminfo: %s", line) Defensive patterns
Strategy: validation
Validate before calling
// Validate line shape before parse: expect 4 fields or 5 with kB unit
parts := strings.Fields(line)
if !(len(parts) == 4 || (len(parts) == 5 && parts[4] == "kB")) {
return fmt.Errorf("unsupported meminfo line shape: %q", line)
} Try / catch
_, err := parseMemInfoNuma(f)
if err != nil {
if strings.Contains(err.Error(), "invalid line in meminfo") {
// fall back to non-NUMA meminfo collector or disable meminfo_numa
}
return err
} Prevention
- Pin node_exporter versions against tested kernel releases
- Check sysfs unit changes after kernel upgrades (kB vs other units)
- Keep fixtures (sys.ttar) updated when testing on new kernels
- Disable meminfo_numa via build tag if your kernel emits unsupported units
When it happens
Trigger: parseMemInfoNuma reads a line whose word count is not 4, or is 5 but the 5th word is not exactly 'kB' — e.g. 'Node 0 MemFree: 1024 MB' or a line with an unexpected trailing column.
Common situations: Kernels emitting units other than kB for per-node meminfo entries; custom kernels or hypervisors adding columns; parsing hand-edited or fixture files; future kernel changes introducing new units.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- invalid value in meminfo
- line scan did not return 2 fields
- invalid value in numastat
- couldn't get NUMA meminfo
- device node string didn't match regexp
AI-assisted analysis of prometheus/node_exporter@17ddd77c59 (2026-09-07).
Data as JSON: /api/errors/5bc67bf1592a2864.
Report an issue: GitHub.
Appendix: source
Thrown at collector/meminfo_numa_linux.go:147
)
for scanner.Scan() {
line := strings.TrimSpace(scanner.Text())
if line == "" {
continue
}
parts := strings.Fields(line)
fv, err := strconv.ParseFloat(parts[3], 64)
if err != nil {
return nil, fmt.Errorf("invalid value in meminfo: %w", err)
}
switch l := len(parts); {
case l == 4: // no unit
case l == 5 && parts[4] == "kB": // has unit
fv *= 1024
default:
return nil, fmt.Errorf("invalid line in meminfo: %s", line)
}
metric := strings.TrimRight(parts[2], ":")
// Active(anon) -> Active_anon
metric = re.ReplaceAllString(metric, "_${1}")
memInfo = append(memInfo, meminfoMetric{metric, prometheus.GaugeValue, parts[1], fv})
}
return memInfo, scanner.Err()
}
func parseMemInfoNumaStat(r io.Reader, nodeNumber string) ([]meminfoMetric, error) {
var (
numaStat []meminfoMetric
scanner = bufio.NewScanner(r)
)
for scanner.Scan() {View on GitHub (pinned to 17ddd77c59)