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

  1. Ensure /sys is mounted sysfs and readable, and that --path.sysfs is correct
  2. Disable the btrfs collector (--no-collector.btrfs) if no btrfs filesystems are used
  3. Check SELinux/AppArmor audit logs and adjust policy to allow reading /sys/fs/btrfs
  4. 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

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


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)