prometheus/node_exporter · error
getdevs() failed
Error message
getdevs() failed
What it means
In the DragonFly BSD devstat collector (devstat_dragonfly.go), Update calls C._get_ndevs() to count block devices via devstat_getdevs. A return of -1 means the underlying getdevs()/devstat_getdevs call failed, so the collector cannot enumerate disk statistics and returns this error.
Solutions
- Ensure the node_exporter user can open /dev/devstat (adjust device permissions or run with adequate privileges)
- Verify the kernel has DEVFS/devstat enabled ('devstat' sysctl or kern.devstat available)
- Run outside restricted jails/containers, or bind-mount/devfs-rule the devstat device into it
- Disable the diskstats/devstat collector on hosts where devstat is unavailable
Defensive patterns
Strategy: validation
Validate before calling
// shell pre-flight: exporter user must reach the devstat device [ -e /dev/devstat ] && [ -r /dev/devstat ] || echo "devstat unavailable; devstat collector will fail"
Prevention
- Grant read access to /dev/devstat via devfs.rules before starting the exporter
- Verify kernel devstat support (kern.devstat sysctl present) at deploy time
- Avoid running inside jails that hide the devstat device, or provide device access
- Prefer disabling the collector over letting every scrape fail
When it happens
Trigger: C._get_ndevs() == -1 in devstatCollector.Update — the C helper's devstat_getdevs or device-enumeration call returned failure, typically because the devstat device (/dev/devstat) cannot be opened or devstat_checkdevs fails.
Common situations: node_exporter run without permission to open /dev/devstat; running in a jail or container without device access; kernel without devstat support compiled/enabled.
Related errors
- calloc() failed
- devstat_getdevs failed
- could not retrieve CPU times
- getmntinfo() failed
- getifaddrs() failed
AI-assisted analysis of prometheus/node_exporter@17ddd77c59 (2026-09-07).
Data as JSON: /api/errors/a170febda6d857d3.
Report an issue: GitHub.
Appendix: source
Thrown at collector/devstat_dragonfly.go:132
),
transfersDesc: prometheus.NewDesc(
prometheus.BuildFQName(namespace, devstatSubsystem, "transfers_total"),
"The total number of transactions completed.",
[]string{"device"}, nil,
),
blocksDesc: prometheus.NewDesc(
prometheus.BuildFQName(namespace, devstatSubsystem, "blocks_total"),
"The total number of bytes given in terms of the devices blocksize.",
[]string{"device"}, nil,
),
logger: logger,
}, nil
}
func (c *devstatCollector) Update(ch chan<- prometheus.Metric) error {
count := C._get_ndevs()
if count == -1 {
return errors.New("getdevs() failed")
}
if count == -2 {
return errors.New("calloc() failed")
}
for i := C.int(0); i < count; i++ {
stats := C._get_stats(i)
device := fmt.Sprintf("%s%d", C.GoString(&stats.device[0]), stats.unit)
ch <- prometheus.MustNewConstMetric(c.bytesDesc, prometheus.CounterValue, float64(stats.bytes), device)
ch <- prometheus.MustNewConstMetric(c.transfersDesc, prometheus.CounterValue, float64(stats.transfers), device)
ch <- prometheus.MustNewConstMetric(c.blocksDesc, prometheus.CounterValue, float64(stats.blocks), device)
}
return nil
}
View on GitHub (pinned to 17ddd77c59)