prometheus/node_exporter · error
failed to open sysfs
Error message
failed to open sysfs: %w
What it means
NewDMMultipathCollector wraps a failure from blockdevice.NewFS(*procPath, *sysPath) as "failed to open sysfs". The block device FS constructor validates both the procfs and sysfs roots; this error indicates one of them could not be used, preventing the dm-multipath collector from being created.
Solutions
- Verify both --path.procfs (default /proc) and --path.sysfs (default /sys) point to mounted, readable directories
- Mount procfs and sysfs into the container: -v /proc:/proc:ro -v /sys:/sys:ro
- Correct any typo or override of the path flags
- Check that the paths are directories, not regular files or symlinks to nothing
Example fix
// before node_exporter --path.sysfs=/sysfs-typo // after node_exporter --path.sysfs=/sys
Defensive patterns
Strategy: validation
Validate before calling
for _, p := range []string{procPath, sysPath} {
if st, err := os.Stat(p); err != nil || !st.IsDir() {
// fix --path.procfs / --path.sysfs before enabling dm-multipath collector
}
} Try / catch
c, err := collector.NewDMMultipathCollector(logger)
if err != nil {
return fmt.Errorf("dm-multipath collector disabled: %w", err)
} Prevention
- Mount both /proc and /sys read-only in containers
- Keep default path flags unless you have a specific mount layout
- Validate paths at service startup with a health check
When it happens
Trigger: blockdevice.NewFS fails because --path.procfs or --path.sysfs does not exist, is unreadable, or is not a directory. Called from NewDMMultipathCollector during collector registration and from the dm-multipath tests.
Common situations: Containerized node_exporter without /sys or /proc mounted; typo'd --path.sysfs/--path.procfs flags; running on non-Linux where the expected mounts are absent despite the build-tag-gated collector being enabled.
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 scan DM-multipath devices
- Could not derive a human-readable chip type for
- failed to open sysfs
- failed to retrieve bcache stats
- failed to open sysfs
AI-assisted analysis of prometheus/node_exporter@17ddd77c59 (2026-09-07).
Data as JSON: /api/errors/b18669c584f62140.
Report an issue: GitHub.
Appendix: source
Thrown at collector/dmmultipath_linux.go:88
)
dmmultipathPathState = prometheus.NewDesc(
prometheus.BuildFQName(namespace, "dmmultipath", "path_state"),
"Reports the underlying device state for a multipath path, as read from /sys/block/<dev>/device/state.",
[]string{"device", "path", "state"}, nil,
)
)
type dmMultipathCollector struct {
fs blockdevice.FS
logger *slog.Logger
}
// NewDMMultipathCollector returns a new Collector exposing Device Mapper
// multipath device metrics from /sys/block/dm-*.
func NewDMMultipathCollector(logger *slog.Logger) (Collector, error) {
fs, err := blockdevice.NewFS(*procPath, *sysPath)
if err != nil {
return nil, fmt.Errorf("failed to open sysfs: %w", err)
}
return &dmMultipathCollector{
fs: fs,
logger: logger,
}, nil
}
func (c *dmMultipathCollector) Update(ch chan<- prometheus.Metric) error {
devices, err := c.fs.DMMultipathDevices()
if err != nil {
if errors.Is(err, os.ErrNotExist) || errors.Is(err, os.ErrPermission) {
c.logger.Debug("Could not read DM-multipath devices", "err", err)
return ErrNoData
}
return fmt.Errorf("failed to scan DM-multipath devices: %w", err)
}
View on GitHub (pinned to 17ddd77c59)