prometheus/node_exporter · error

couldn't get

Error message

couldn't get %s: %w

What it means

slabinfoCollector.Update wraps errors from fs.SlabInfo() with "couldn't get slabinfo: %w". The collector was constructed successfully, but reading or parsing /proc/slabinfo via procfs failed during a scrape.

Solutions

  1. Run node_exporter with privileges sufficient to read /proc/slabinfo (often root)
  2. Update github.com/prometheus/procfs to a version that parses your kernel's slabinfo
  3. Leave the slabinfo collector disabled (it is defaultDisabled) if the data is not needed

Example fix

// before (go.mod)
github.com/prometheus/procfs v0.9.0
// after
go get github.com/prometheus/procfs@latest && go mod tidy
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-check readability before enabling
if f, err := os.Open("/proc/slabinfo"); err != nil {
	// slabinfo unreadable; keep collector disabled
} else {
	f.Close()
}

Try / catch

if err := collector.Update(ch); err != nil {
	var msg string
	if _, perr := fmt.Sscanf(err.Error(), "couldn't get slabinfo:"); perr == nil {
		logger.Warn("slabinfo scrape failed", "err", err)
	} else {
		return err
	}
}

Prevention

When it happens

Trigger: fs.SlabInfo() returning an error at scrape time: /proc/slabinfo became unreadable, or the kernel's slabinfo content could not be parsed by the vendored procfs version.

Common situations: Hardened kernels restricting /proc/slabinfo to privileged users; kernels newer than the procfs dependency with a changed slabinfo format.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


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

Appendix: source

Thrown at collector/slabinfo_linux.go:61

func NewSlabinfoCollector(logger *slog.Logger) (Collector, error) {
	fs, err := procfs.NewFS(*procPath)
	if err != nil {
		return nil, fmt.Errorf("failed to open procfs: %w", err)
	}

	return &slabinfoCollector{logger: logger,
		fs:             fs,
		subsystem:      "slabinfo",
		labels:         []string{"slab"},
		slabNameFilter: newDeviceFilter(*slabNameExclude, *slabNameInclude),
	}, nil
}

func (c *slabinfoCollector) Update(ch chan<- prometheus.Metric) error {
	slabinfo, err := c.fs.SlabInfo()
	if err != nil {
		return fmt.Errorf("couldn't get %s: %w", c.subsystem, err)
	}

	for _, slab := range slabinfo.Slabs {
		if c.slabNameFilter.ignored(slab.Name) {
			continue
		}
		ch <- c.activeObjects(slab.Name, slab.ObjActive)
		ch <- c.objects(slab.Name, slab.ObjNum)
		ch <- c.objectSizeBytes(slab.Name, slab.ObjSize)
		ch <- c.objectsPerSlab(slab.Name, slab.ObjPerSlab)
		ch <- c.pagesPerSlab(slab.Name, slab.PagesPerSlab)
	}

	return nil
}

func (c *slabinfoCollector) activeObjects(label string, val int64) prometheus.Metric {
	desc := prometheus.NewDesc(

View on GitHub (pinned to 17ddd77c59)