prometheus/node_exporter · error
couldn't get memory
Error message
couldn't get memory: %w
What it means
memoryCollector.Update iterates the configured sysctl metrics and calls m.Value() for each; if any sysctl read fails, the whole scrape aborts with this wrapped error. node_exporter throws it because one of the vm.stats.* sysctls backing the memory metrics could not be read during a collection cycle.
Solutions
- Check which sysctl fails by running the MIBs manually with `sysctl <name>` as the exporter's user
- Grant the exporter user read access or run with appropriate privileges
- If in a jail, enable the needed sysctl visibility for the jail
- Update node_exporter/kernel so the MIB set matches
Example fix
// before: one failing sysctl fails the whole scrape
v, err := m.Value()
if err != nil {
return fmt.Errorf("couldn't get memory: %w", err)
}
// after (caller-side mitigation in a wrapper/scrape config)
if _, err := unix.SysctlUint32("vm.stats.vm.v_free_count"); err != nil {
// fix access first: run `sysctl vm.stats.vm.v_free_count` as exporter user
logger.Warn("memory sysctl unavailable; memory metrics will be missing")
} Defensive patterns
Strategy: retry
Validate before calling
for mib in vm.stats.vm.v_page_size vm.stats.vm.v_free_count vm.stats.vm.v_inactive_count; do sysctl -n "$mib" >/dev/null || echo "missing: $mib" done
Try / catch
if err := c.Update(ch); err != nil {
if strings.Contains(err.Error(), "couldn't get memory") {
// transient sysctl failure: retry the scrape once
runtime.Gosched()
return c.Update(ch)
}
return err
} Prevention
- Grant the exporter user sysctl read access
- Alert on 'couldn't get memory' scrape errors to catch MIB drift after kernel upgrades
- Test scrapes in staging after every kernel upgrade
When it happens
Trigger: A Prometheus scrape of the memory collector on FreeBSD/DragonFly when any sysctl in c.sysctls (e.g. vm.stats.vm.v_free_count) returns an error — missing MIB, permission denial, or transient kernel error.
Common situations: Jails with restricted sysctl visibility; kernel upgrades changing/renaming vm.stats MIBs; running the exporter as an unprivileged user without sysctl read access.
Related errors
- sysctl(vm.stats.vm.v_page_size) failed
- couldn't get kvm
- Data Size mismatch
- failed to get memory info
- sysctl CTL_VFS VFS_GENERIC VFS_BCACHESTAT failed
AI-assisted analysis of prometheus/node_exporter@17ddd77c59 (2026-09-07).
Data as JSON: /api/errors/4b3a816ebf2b58ea.
Report an issue: GitHub.
Appendix: source
Thrown at collector/memory_bsd.go:151
},
{
name: "swap_out_bytes_total",
description: "Bytes paged out to swap devices",
mib: "vm.stats.vm.v_swappgsout",
valueType: prometheus.CounterValue,
conversion: fromPage,
},
},
}, nil
}
// Update checks relevant sysctls for current memory usage, and kvm for swap
// usage.
func (c *memoryCollector) Update(ch chan<- prometheus.Metric) error {
for _, m := range c.sysctls {
v, err := m.Value()
if err != nil {
return fmt.Errorf("couldn't get memory: %w", err)
}
// Most are gauges.
if m.valueType == 0 {
m.valueType = prometheus.GaugeValue
}
ch <- prometheus.MustNewConstMetric(
prometheus.NewDesc(
prometheus.BuildFQName(namespace, memorySubsystem, m.name),
m.description,
nil, nil,
), m.valueType, v)
}
swapUsed, err := c.kvm.SwapUsedPages()
if err != nil {
return fmt.Errorf("couldn't get kvm: %w", err)View on GitHub (pinned to 17ddd77c59)