prometheus/node_exporter · error

device-exclude & device-include are mutually exclusive

Error message

device-exclude & device-include are mutually exclusive

What it means

newDiskstatsDeviceFilter (diskstats_common.go) rejects configurations where both --collector.diskstats.device-exclude and --collector.diskstats.device-include are set to non-empty values, since a device cannot simultaneously be filtered in and out. The filter intentionally clears the exclude value when only an include is given, but errors if both were explicitly configured.

Solutions

  1. Pick one filtering style: keep --collector.diskstats.device-include alone (excludes are cleared) or keep --collector.diskstats.device-exclude and remove the include flag
  2. Combine the patterns into a single regex for the flag you keep
  3. Audit config management templates so only one of the two flags is ever rendered

Example fix

// before
node_exporter --collector.diskstats.device-include='^(sd|nvme)' --collector.diskstats.device-exclude='^(loop|ram)'
// after
node_exporter --collector.diskstats.device-include='^(sd|nvme)'
Defensive patterns

Strategy: validation

Validate before calling

# pre-flight: device-include and device-exclude must never both be set
if echo "$NODE_EXPORTER_ARGS" | grep -q 'diskstats.device-include=' && echo "$NODE_EXPORTER_ARGS" | grep -q 'diskstats.device-exclude='; then
  echo "conflict: keep only one of device-include / device-exclude"
fi

Prevention

When it happens

Trigger: diskstatsDeviceInclude != "" AND diskstatsDeviceExcludeSet AND *diskstatsDeviceExclude != "" — i.e. both --collector.diskstats.device-include and --collector.diskstats.device-exclude supplied with non-empty values on the command line.

Common situations: Operators migrating between allowlist and denylist styles who forgot to delete the other flag; copy-pasting example command lines that contain both flags; layered config management assigning each flag at a different scope.

Understand the failure class

Background: "mutually exclusive" flag errors: what "can't supply both nx and xx", "--raw is not compatible with -i" and "cannot be used with" mean, and how to fix them — this error's family across 29 libraries.

Related errors


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

Appendix: source

Thrown at collector/diskstats_common.go:104

		prometheus.BuildFQName(namespace, diskSubsystem, "write_time_seconds_total"),
		"This is the total number of seconds spent by all writes.",
		diskLabelNames,
		nil,
	)
)

func newDiskstatsDeviceFilter(logger *slog.Logger) (deviceFilter, error) {
	if *oldDiskstatsDeviceExclude != "" {
		if !diskstatsDeviceExcludeSet {
			logger.Warn("--collector.diskstats.ignored-devices is DEPRECATED and will be removed in 2.0.0, use --collector.diskstats.device-exclude")
			*diskstatsDeviceExclude = *oldDiskstatsDeviceExclude
		} else {
			return deviceFilter{}, errors.New("--collector.diskstats.ignored-devices and --collector.diskstats.device-exclude are mutually exclusive")
		}
	}
	if *diskstatsDeviceInclude != "" {
		if diskstatsDeviceExcludeSet && *diskstatsDeviceExclude != "" {
			return deviceFilter{}, errors.New("device-exclude & device-include are mutually exclusive")
		}
		*diskstatsDeviceExclude = ""
	}

	if *diskstatsDeviceExclude != "" {
		logger.Info("Parsed flag --collector.diskstats.device-exclude", "flag", *diskstatsDeviceExclude)
	}

	if *diskstatsDeviceInclude != "" {
		logger.Info("Parsed Flag --collector.diskstats.device-include", "flag", *diskstatsDeviceInclude)
	}

	return newDeviceFilter(*diskstatsDeviceExclude, *diskstatsDeviceInclude), nil
}

View on GitHub (pinned to 17ddd77c59)