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);
}
@OverrideView on GitHub (pinned to c31c9215e1)
Solutions
- Inspect PluginMetricsImpl's reserved tags for your framework version and remove any of those keys from your plugin's tag map.
- Prefix plugin-specific tag names (e.g. "my-plugin-stage") so they cannot collide with reserved framework tags.
- Log tags.keySet() vs the reserved set when the exception fires to identify the exact overlapping key.
- 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
- Never reuse framework identity tags (e.g. client-id / connector-name) as your own metric tags.
- Prefix custom tag names with a plugin-specific namespace to avoid collisions.
- If unsure which tags are reserved, catch IllegalArgumentException once to discover them, then add them to a blocklist.
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
- For '{templateName}', runtime-defined metric tags do not mat
- keyValue needs to be specified in pairs
- This PluginMetrics instance is closed
- Metric {metricName} already exists
- Telemetry is not enabled. Set config `enable.metrics.push` t
AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03).
Data as JSON: /data/errors/ccd94649cf1baf2e.json.
Report an issue: GitHub.