prometheus/node_exporter · error

--collector.netdev.device-whitelist and…

Error message

--collector.netdev.device-whitelist and --collector.netdev.device-include are mutually exclusive

What it means

The netdev collector accepts device filters via new flags (--collector.netdev.device-include) and deprecated aliases (--collector.netdev.device-whitelist). If both the old and new include flags are set to non-empty values, the collector refuses to guess which to use and returns this mutually-exclusive error at construction time (NewNetDevCollector), so the netdev collector never starts.

Solutions

  1. Remove the deprecated --collector.netdev.device-whitelist flag and keep only --collector.netdev.device-include.
  2. Search all launch points (systemd units, Docker CMD/args, k8s manifests, config management) for the old flag and delete it.
  3. If you must keep old flags during a rollout, set only the old flag — it is migrated automatically with a warning — but plan removal before 2.0.0.
  4. Restart node_exporter after cleaning the flags; the collector will start normally.

Example fix

// before
node_exporter --collector.netdev.device-whitelist=eth0 --collector.netdev.device-include=eth1
// after
node_exporter --collector.netdev.device-include=eth1
Defensive patterns

Strategy: validation

Validate before calling

# Before launching node_exporter, assert the flag pair is not duplicated
if [[ -n "$WHITELIST" && -n "$INCLUDE" ]]; then
  echo "ERROR: device-whitelist and device-include are mutually exclusive" >&2
  exit 1
fi

Try / catch

c, err := NewNetDevCollector(logger)
if err != nil && strings.Contains(err.Error(), "mutually exclusive") {
    logger.Error("netdev flag conflict in launch configuration", "err", err)
    os.Exit(2) // fail fast at startup; configuration error, not transient
}

Prevention

When it happens

Trigger: Starting node_exporter with BOTH --collector.netdev.device-whitelist and --collector.netdev.device-include set to non-empty values, e.g. `--collector.netdev.device-whitelist=eth0 --collector.netdev.device-include=eth1`. If only the old flag is set, it is silently migrated with a deprecation warning instead.

Common situations: Flag migration: operators update configs/scripts to the new flag but an old systemd unit, chef/puppet manifest, or dropped-in args file still passes the deprecated whitelist flag; layered configuration (base image flags + override file) accumulating both flags.

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/f6d6e441f0ce24db. Report an issue: GitHub.

Appendix: source

Thrown at collector/netdev_common.go:60

	metricDescsMutex sync.Mutex
	metricDescs      map[string]*prometheus.Desc
	logger           *slog.Logger
}

type netDevStats map[string]map[string]uint64

func init() {
	registerCollector("netdev", defaultEnabled, NewNetDevCollector)
}

// NewNetDevCollector returns a new Collector exposing network device stats.
func NewNetDevCollector(logger *slog.Logger) (Collector, error) {
	if *oldNetdevDeviceInclude != "" {
		if *netdevDeviceInclude == "" {
			logger.Warn("--collector.netdev.device-whitelist is DEPRECATED and will be removed in 2.0.0, use --collector.netdev.device-include")
			*netdevDeviceInclude = *oldNetdevDeviceInclude
		} else {
			return nil, errors.New("--collector.netdev.device-whitelist and --collector.netdev.device-include are mutually exclusive")
		}
	}

	if *oldNetdevDeviceExclude != "" {
		if *netdevDeviceExclude == "" {
			logger.Warn("--collector.netdev.device-blacklist is DEPRECATED and will be removed in 2.0.0, use --collector.netdev.device-exclude")
			*netdevDeviceExclude = *oldNetdevDeviceExclude
		} else {
			return nil, errors.New("--collector.netdev.device-blacklist and --collector.netdev.device-exclude are mutually exclusive")
		}
	}

	if *netdevDeviceExclude != "" && *netdevDeviceInclude != "" {
		return nil, errors.New("device-exclude & device-include are mutually exclusive")
	}

	if *netdevDeviceExclude != "" {
		logger.Info("Parsed flag --collector.netdev.device-exclude", "flag", *netdevDeviceExclude)

View on GitHub (pinned to 17ddd77c59)