apache/kafka · error · IllegalArgumentException

Cannot use {tagName} as a tag name

Error message

Cannot use {tagName} as a tag name

What it means

Thrown by PluginMetricsImpl.metricName when one of the caller-supplied tag keys is already present in the instance's reserved tag map (this.tags). PluginMetricsImpl prepends a fixed set of tags (group "plugins" plus plugin-identifying tags) to every metric name; allowing a plugin to overwrite them would corrupt the namespace and break metric identity. The collision is rejected with IllegalArgumentException naming the offending tag.

Source

Thrown at clients/src/main/java/org/apache/kafka/common/metrics/internals/PluginMetricsImpl.java:52

    private static final String GROUP = "plugins";

    private final Metrics metrics;
    private final Map<String, String> tags;
    private final Set<MetricName> metricNames = ConcurrentHashMap.newKeySet();
    private final Set<String> sensors = ConcurrentHashMap.newKeySet();
    private volatile boolean closing = false;

    public PluginMetricsImpl(Metrics metrics, Map<String, String> tags) {
        this.metrics = metrics;
        this.tags = tags;
    }

    @Override
    public MetricName metricName(String name, String description, LinkedHashMap<String, String> tags) {
        if (closing) throw new IllegalStateException("This PluginMetrics instance is closed");
        for (String tagName : tags.keySet()) {
            if (this.tags.containsKey(tagName)) {
                throw new IllegalArgumentException("Cannot use " + tagName + " as a tag name");
            }
        }
        Map<String, String> metricsTags = new LinkedHashMap<>(this.tags);
        metricsTags.putAll(tags);
        return metrics.metricName(name, GROUP, description, metricsTags);
    }

    @Override
    public void addMetric(MetricName metricName, MetricValueProvider<?> metricValueProvider) {
        if (closing) throw new IllegalStateException("This PluginMetrics instance is closed");
        if (metricNames.contains(metricName)) {
            throw new IllegalArgumentException("Metric " + metricName + " already exists");
        }
        metrics.addMetric(metricName, metricValueProvider);
        metricNames.add(metricName);
    }

    @Override

View on GitHub (pinned to c31c9215e1)

Solutions

  1. Inspect PluginMetricsImpl's reserved tags for your framework version and remove any of those keys from your plugin's tag map.
  2. Prefix plugin-specific tag names (e.g. "my-plugin-stage") so they cannot collide with reserved framework tags.
  3. Log tags.keySet() vs the reserved set when the exception fires to identify the exact overlapping key.
  4. Update the plugin to the framework's current reserved-tag contract (check the PluginMetrics instance tags at construction).

Example fix

// before
LinkedHashMap<String,String> tags = new LinkedHashMap<>();
tags.put("plugin-name", "my-plugin"); // reserved by framework
MetricName n = pluginMetrics.metricName("rx", "desc", tags); // throws

// after
LinkedHashMap<String,String> tags = new LinkedHashMap<>();
tags.put("stage", "fetch"); // non-reserved key
MetricName n = pluginMetrics.metricName("rx", "desc", tags);
Defensive patterns

Strategy: validation

Validate before calling

// reservedTagNames = the identity tags owned by the PluginMetrics instance (e.g. client/connector id).
// Strip or rename any caller-supplied tag that collides with them.
Set<String> reservedTagNames = Set.of(/* framework identity tag keys */);
LinkedHashMap<String, String> safeTags = new LinkedHashMap<>();
for (Map.Entry<String, String> e : callerTags.entrySet()) {
    if (!reservedTagNames.contains(e.getKey())) {
        safeTags.put(e.getKey(), e.getValue());
    }
}
pluginMetrics.metricName(name, description, safeTags);

Type guard

static boolean hasNoReservedTags(LinkedHashMap<String, String> tags, Set<String> reserved) {
    for (String k : tags.keySet()) if (reserved.contains(k)) return false;
    return true;
}

Prevention

When it happens

Trigger: Calling pluginMetrics.metricName(name, description, tags) where tags.keySet() intersects this.tags (the reserved tags assigned at PluginMetricsImpl construction, e.g. plugin-name / plugin-id). Any duplicate key triggers the exception before the maps are merged.

Common situations: A plugin that adds a generic tag like "plugin" or "client-id" that the framework already injects; refactors that change which tags the framework reserves without updating plugins; a plugin reused across framework versions where the reserved-tag set differs.

Related errors


AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03). Data as JSON: /data/errors/ccd94649cf1baf2e.json. Report an issue: GitHub.