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
- Remove the deprecated --collector.netdev.device-whitelist flag and keep only --collector.netdev.device-include.
- Search all launch points (systemd units, Docker CMD/args, k8s manifests, config management) for the old flag and delete it.
- 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.
- 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
- Standardize on the new flags (device-include/device-exclude) and delete deprecated ones repo-wide.
- Add a startup smoke test that runs node_exporter --collector.disable-defaults --collector.netdev to catch flag conflicts in CI.
- Audit systemd drop-ins and container arg layers that can accumulate duplicate flags.
- Read startup logs for the DEPRECATED warning — it signals a flag that will hard-fail if paired later.
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
- --collector.netdev.device-blacklist and…
- device-exclude & device-include are mutually exclusive
- --collector.diskstats.ignored-devices and…
- device-exclude & device-include are mutually exclusive
- --collector.filesystem.ignored-mount-points and…
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)