prometheus/node_exporter · error
failed to open sysfs
Error message
failed to open sysfs: %w
What it means
On Linux, NewDiskstatsCollector opens the proc/sys filesystem with blockdevice.NewFS(*procPath, *sysPath) before building the collector. If that filesystem handle cannot be created (path missing, not a directory, or stat/permission errors), construction fails with "failed to open sysfs: %w".
Solutions
- Verify both paths exist and are directories: ls -d /proc /sys (or the values of --path.procfs / --path.sysfs).
- In containers, mount /proc and /sys into the container (e.g. -v /proc:/host/proc:ro -v /sys:/host/sys:ro with matching --path.* flags).
- Fix the incorrect --path.procfs / --path.sysfs flag values.
- Inspect the wrapped cause (%w) for permission errors and adjust the run user or mount options.
- Disable the diskstats collector if disk metrics are not required (--no-collector.diskstats).
Example fix
// before (container without mounts) docker run prom/node-exporter --path.procfs=/host/proc // after docker run -v /proc:/host/proc:ro -v /sys:/host/sys:ro prom/node-exporter --path.procfs=/host/proc --path.sysfs=/host/sys
Defensive patterns
Strategy: validation
Validate before calling
for _, p := range []string{procPath, sysPath} {
fi, err := os.Stat(p)
if err != nil || !fi.IsDir() {
// invalid --path.procfs/--path.sysfs; fix before starting
}
} Try / catch
if _, err := NewDiskstatsCollector(logger); err != nil {
var perr *fs.PathError
if errors.As(err, &perr) {
log.Fatalf("proc/sys path invalid: %v", perr)
}
log.Fatalf("diskstats init failed: %v", err)
} Prevention
- Mount both /proc and /sys read-only into containers with matching --path.* flags.
- Verify path flags in deployment tooling before rollout.
- Run the exporter as a user that can stat proc/sys mounts.
- Disable the diskstats collector on hosts without these mounts.
When it happens
Trigger: node_exporter startup with the diskstats collector enabled when blockdevice.NewFS fails: --path.procfs or --path.sysfs points to a nonexistent/non-directory path, or permission errors occur validating either mount.
Common situations: Wrong --path.procfs/--path.sysfs values; containers missing /proc or /sys mounts; restricted environments where the exporter user cannot stat those paths; chroot/minimal images without the expected mounts.
Understand the failure class
Background: "open() failed", "failed to open file", "cannot create file" — what a file open error means and how to fix it — this error's family across 42 libraries.
Related errors
- failed to get vulnerabilities
- couldn't get diskstats
- error obtaining power_supply class info
- Could not derive a human-readable chip type for
- interrupts empty
AI-assisted analysis of prometheus/node_exporter@17ddd77c59 (2026-09-07).
Data as JSON: /api/errors/69cd889a9698b352.
Report an issue: GitHub.
Appendix: source
Thrown at collector/diskstats_linux.go:92
descs []typedDesc
filesystemInfoDesc typedDesc
deviceMapperInfoDesc typedDesc
ataDescs map[string]typedDesc
logger *slog.Logger
getUdevDeviceProperties func(uint32, uint32) (udevInfo, error)
}
func init() {
registerCollector("diskstats", defaultEnabled, NewDiskstatsCollector)
}
// NewDiskstatsCollector returns a new Collector exposing disk device stats.
// Docs from https://www.kernel.org/doc/Documentation/iostats.txt
func NewDiskstatsCollector(logger *slog.Logger) (Collector, error) {
var diskLabelNames = []string{"device"}
fs, err := blockdevice.NewFS(*procPath, *sysPath)
if err != nil {
return nil, fmt.Errorf("failed to open sysfs: %w", err)
}
deviceFilter, err := newDiskstatsDeviceFilter(logger)
if err != nil {
return nil, fmt.Errorf("failed to parse device filter flags: %w", err)
}
collector := diskstatsCollector{
deviceFilter: deviceFilter,
fs: fs,
infoDesc: typedDesc{
desc: prometheus.NewDesc(prometheus.BuildFQName(namespace, diskSubsystem, "info"),
"Info of /sys/block/<block_device>.",
[]string{"device", "major", "minor", "path", "wwn", "model", "serial", "revision", "rotational"},
nil,
), valueType: prometheus.GaugeValue,
},
descs: []typedDesc{View on GitHub (pinned to 17ddd77c59)