prometheus/node_exporter · error

failed to parse device filter flags

Error message

failed to parse device filter flags: %w

What it means

On OpenBSD, NewDiskstatsCollector compiles the device include/exclude flag regexes through newDiskstatsDeviceFilter(logger) before constructing the collector. Invalid regex flags cause construction to fail with "failed to parse device filter flags: %w".

Solutions

  1. Read the wrapped regexp error (%w) to find the bad token and correct the flag value.
  2. Quote the flag value in the shell to protect [ ] ( ) * characters.
  3. Test the pattern in a Go regex validator before deployment.
  4. Run without the filter flag to verify the collector constructs, then add back a valid pattern.

Example fix

// before
--collector.diskstats.device-exclude=sd[!0-9]
// after (Go RE2 lacks [!...]; use negated class)
--collector.diskstats.device-exclude='sd[^0-9]'
Defensive patterns

Strategy: validation

Validate before calling

if _, err := regexp.Compile(deviceFilterFlag); err != nil {
    // invalid --collector.diskstats.device-* value; fix before start
}

Try / catch

if _, err := NewDiskstatsCollector(logger); err != nil {
    if strings.Contains(err.Error(), "failed to parse device filter flags") {
        log.Fatalf("invalid device filter regex: %v", err)
    }
    log.Fatalf("diskstats init failed: %v", err)
}

Prevention

When it happens

Trigger: node_exporter startup on OpenBSD with --collector.diskstats.device-exclude (or include) set to a value regexp.Compile rejects; identical for direct NewDiskstatsCollector calls.

Common situations: Shell-mangled unquoted patterns (glob expansion of ? and *), unbalanced brackets/parens, or regexes borrowed from non-Go syntax dialects.

Understand the failure class

Related errors


AI-assisted analysis of prometheus/node_exporter@17ddd77c59 (2026-09-07). Data as JSON: /api/errors/7587f817bbd3d7fb. Report an issue: GitHub.

Appendix: source

Thrown at collector/diskstats_openbsd.go:54

	rxfer  typedDesc
	rbytes typedDesc
	wxfer  typedDesc
	wbytes typedDesc
	time   typedDesc

	deviceFilter deviceFilter
	logger       *slog.Logger
}

func init() {
	registerCollector("diskstats", defaultEnabled, NewDiskstatsCollector)
}

// NewDiskstatsCollector returns a new Collector exposing disk device stats.
func NewDiskstatsCollector(logger *slog.Logger) (Collector, error) {
	deviceFilter, err := newDiskstatsDeviceFilter(logger)
	if err != nil {
		return nil, fmt.Errorf("failed to parse device filter flags: %w", err)
	}

	return &diskstatsCollector{
		rxfer:  typedDesc{readsCompletedDesc, prometheus.CounterValue},
		rbytes: typedDesc{readBytesDesc, prometheus.CounterValue},
		wxfer:  typedDesc{writesCompletedDesc, prometheus.CounterValue},
		wbytes: typedDesc{writtenBytesDesc, prometheus.CounterValue},
		time:   typedDesc{ioTimeSecondsDesc, prometheus.CounterValue},

		deviceFilter: deviceFilter,
		logger:       logger,
	}, nil
}

func (c *diskstatsCollector) Update(ch chan<- prometheus.Metric) (err error) {
	diskstatsb, err := unix.SysctlRaw("hw.diskstats")
	if err != nil {
		return err

View on GitHub (pinned to 17ddd77c59)