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

  1. Check which sysctl fails by running the MIBs manually with `sysctl <name>` as the exporter's user
  2. Grant the exporter user read access or run with appropriate privileges
  3. If in a jail, enable the needed sysctl visibility for the jail
  4. 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

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


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)