prometheus/node_exporter · error

sysctl(vm.stats.vm.v_page_size) failed

Error message

sysctl(vm.stats.vm.v_page_size) failed: %w

What it means

NewMemoryCollector on FreeBSD/DragonFly BSD reads the page size via unix.SysctlUint32("vm.stats.vm.v_page_size") before constructing the collector. If that sysctl fails (missing MIB or permission error), collector creation aborts and the wrapped error is returned. This means the memory collector cannot be initialized because a fundamental kernel value is unavailable.

Solutions

  1. Run node_exporter as a user permitted to read vm.stats.vm.v_page_size (verify: `sysctl vm.stats.vm.v_page_size`)
  2. Confirm the target OS actually exposes this MIB; if running a non-FreeBSD/DragonFly BSD, use the platform-appropriate build
  3. Check jail/sandbox settings (security.jail.* sysctls) to allow vm.* sysctls inside the jail
  4. Upgrade node_exporter in case the MIB handling changed for your kernel version

Example fix

// before
size, err := unix.SysctlUint32("vm.stats.vm.v_page_size")
if err != nil {
	return nil, fmt.Errorf("sysctl(vm.stats.vm.v_page_size) failed: %w", err)
}
// after (caller-side verification before deployment)
// $ sysctl vm.stats.vm.v_page_size  -> must print a value; otherwise fix
// permissions or OS choice before starting node_exporter
Defensive patterns

Strategy: validation

Validate before calling

// run before starting the exporter
if ! sysctl -n vm.stats.vm.v_page_size >/dev/null 2>&1; then
  echo 'vm.stats.vm.v_page_size unavailable - memory collector will fail'
  exit 1
fi

Try / catch

c, err := NewMemoryCollector(logger)
if err != nil {
	logger.Error("memory collector disabled", "err", err)
	// register remaining collectors and continue
}

Prevention

When it happens

Trigger: Instantiating the memory collector on a BSD kernel where the vm.stats.vm.v_page_size MIB does not exist (e.g. non-FreeBSD/DragonFly kernels reaching this file via build tags) or where sysctl access is denied to the running user.

Common situations: Running node_exporter in a jail or sandbox that restricts vm.* sysctls; porting/building for a BSD variant lacking the vm.stats tree; kernel version changes renaming MIBs.

Related errors


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

Appendix: source

Thrown at collector/memory_bsd.go:45

	memorySubsystem = "memory"
)

type memoryCollector struct {
	pageSize uint64
	sysctls  []bsdSysctl
	kvm      kvm
	logger   *slog.Logger
}

func init() {
	registerCollector("meminfo", defaultEnabled, NewMemoryCollector)
}

// NewMemoryCollector returns a new Collector exposing memory stats.
func NewMemoryCollector(logger *slog.Logger) (Collector, error) {
	tmp32, err := unix.SysctlUint32("vm.stats.vm.v_page_size")
	if err != nil {
		return nil, fmt.Errorf("sysctl(vm.stats.vm.v_page_size) failed: %w", err)
	}
	size := float64(tmp32)

	mibSwapTotal := "vm.swap_total"
	/* swap_total is FreeBSD specific. Fall back to Dfly specific mib if not present. */
	_, err = unix.SysctlUint64(mibSwapTotal)
	if err != nil {
		mibSwapTotal = "vm.swap_size"
	}

	fromPage := func(v float64) float64 {
		return v * size
	}

	return &memoryCollector{
		logger:   logger,
		pageSize: uint64(tmp32),
		sysctls: []bsdSysctl{

View on GitHub (pinned to 17ddd77c59)