prometheus/node_exporter · error
failed to open sysfs
Error message
failed to open sysfs: %w
What it means
NewBtrfsCollector wraps errors from btrfs.NewFS(*sysPath) in "failed to open sysfs". The sysfs handle needed to read /sys/fs/btrfs statistics could not be created, so the btrfs collector fails to initialize. Like the other collectors, this surfaces at node_exporter startup when the collector is enabled.
Solutions
- Ensure /sys is mounted sysfs and readable, and that --path.sysfs is correct
- Disable the btrfs collector (--no-collector.btrfs) if no btrfs filesystems are used
- Check SELinux/AppArmor audit logs and adjust policy to allow reading /sys/fs/btrfs
- Run with host namespaces in Kubernetes (hostPID/mount /sys:ro) when containerized
Example fix
// before
collector, err := NewNodeCollector(logger, "btrfs")
// after
if _, err := os.Stat(filepath.Join(*sysPath, "fs", "btrfs")); err != nil {
logger.Info("btrfs sysfs missing; not enabling collector")
return nil
}
collector, err = NewNodeCollector(logger, "btrfs") Defensive patterns
Strategy: fallback
Validate before calling
if fi, err := os.Stat(filepath.Join(*sysPath, "fs", "btrfs")); err != nil || !fi.IsDir() { /* skip btrfs collector */ } Type guard
func btrfsSysfsPresent(sysPath string) bool { fi, err := os.Stat(filepath.Join(sysPath, "fs", "btrfs")); return err == nil && fi.IsDir() } Try / catch
c, err := collector.NewNodeCollector(logger)
if err != nil {
logger.Warn("btrfs collector unavailable", "err", err)
c = nil
} Prevention
- Enable btrfs collector only on hosts using btrfs
- Ensure /sys is mounted ro in containers
- Validate --path.sysfs at deployment time
- Review SELinux/AppArmor policies for /sys/fs/btrfs access
When it happens
Trigger: Enabling the btrfs collector where /sys is absent/not sysfs, --path.sysfs points to a wrong path, permissions deny access, or on kernels/environments where the btrfs sysfs directory structure is missing.
Common situations: Containerized node_exporter without /sys mounted; hosts with CONFIG_BTRFS_FS but no btrfs sysfs exposure; custom test setups passing an invalid sysPath; LSM policy blocking /sys traversal.
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 open sysfs
- failed to open sysfs
- failed to retrieve Btrfs stats from procfs
- failed to open sysfs
- failed to open sysfs
AI-assisted analysis of prometheus/node_exporter@17ddd77c59 (2026-09-07).
Data as JSON: /api/errors/50d9ba090b8306d2.
Report an issue: GitHub.
Appendix: source
Thrown at collector/btrfs_linux.go:44
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/procfs/btrfs"
)
// A btrfsCollector is a Collector which gathers metrics from Btrfs filesystems.
type btrfsCollector struct {
fs btrfs.FS
logger *slog.Logger
}
func init() {
registerCollector("btrfs", defaultEnabled, NewBtrfsCollector)
}
// NewBtrfsCollector returns a new Collector exposing Btrfs statistics.
func NewBtrfsCollector(logger *slog.Logger) (Collector, error) {
fs, err := btrfs.NewFS(*sysPath)
if err != nil {
return nil, fmt.Errorf("failed to open sysfs: %w", err)
}
return &btrfsCollector{
fs: fs,
logger: logger,
}, nil
}
// Update retrieves and exports Btrfs statistics.
// It implements Collector.
func (c *btrfsCollector) Update(ch chan<- prometheus.Metric) error {
stats, err := c.fs.Stats()
if err != nil {
return fmt.Errorf("failed to retrieve Btrfs stats from procfs: %w", err)
}
ioctlStatsMap, err := c.getIoctlStats()
if err != nil {View on GitHub (pinned to 17ddd77c59)