apache/kafka · error · IllegalArgumentException
For '{templateName}', runtime-defined metric tags do not mat
Error message
For '{templateName}', runtime-defined metric tags do not match the tags in the template. Runtime = {runtimeTagKeys} Template = {templateTagKeys} What it means
Thrown by Metrics.metricInstance when the runtime tag key set supplied to instantiate a MetricNameTemplate does not exactly equal the template's declared tag key set. Templates exist to enforce uniform metric tag schemas across the codebase; metricInstance compares runtime keys (merged with the global MetricConfig.tags()) against template.tags() and rejects any drift (missing or extra keys).
Source
Thrown at clients/src/main/java/org/apache/kafka/common/metrics/Metrics.java:677
/* For testing use only. */
Map<Sensor, List<Sensor>> childrenSensors() {
return Collections.unmodifiableMap(childrenSensors);
}
public MetricName metricInstance(MetricNameTemplate template, String... keyValue) {
return metricInstance(template, MetricsUtils.getTags(keyValue));
}
public MetricName metricInstance(MetricNameTemplate template, Map<String, String> tags) {
// check to make sure that the runtime defined tags contain all the template tags.
Set<String> runtimeTagKeys = new HashSet<>(tags.keySet());
runtimeTagKeys.addAll(config().tags().keySet());
Set<String> templateTagKeys = template.tags();
if (!runtimeTagKeys.equals(templateTagKeys)) {
throw new IllegalArgumentException("For '" + template.name() + "', runtime-defined metric tags do not match the tags in the template. "
+ "Runtime = " + runtimeTagKeys + " Template = " + templateTagKeys.toString());
}
return this.metricName(template.name(), template.group(), template.description(), tags);
}
/**
* Close this metrics repository.
*/
@Override
public void close() {
if (this.metricsScheduler != null) {
this.metricsScheduler.shutdown();
try {
this.metricsScheduler.awaitTermination(30, TimeUnit.SECONDS);
} catch (InterruptedException ex) {
// ignore and continue shutdown
Thread.currentThread().interrupt();View on GitHub (pinned to c31c9215e1)
Solutions
- Read the error message: it lists Runtime = {...} and Template = {...}; add the missing keys and remove the extras from your metricInstance call.
- If the template is what should change, update MetricNameTemplate's tags to match the desired schema and audit every call site.
- Keep template tag schemas in a single constants class and have callers reference the same keys to avoid drift.
- If a tag should be applied globally to every metric, put it in MetricConfig.tags() rather than passing it per-call.
Example fix
// before: MetricName n = metrics.metricInstance(template, "client-id", clientId); // template expects {node-id}
// after: MetricName n = metrics.metricInstance(template, "node-id", nodeId); Defensive patterns
Strategy: validation
Validate before calling
// Build the exact tag set the template expects, then call metricInstance.
Set<String> expected = template.tags();
Map<String,String> tags = new LinkedHashMap<>();
for (String k : expected) tags.put(k, resolveValue(k));
// merge with MetricConfig-level tags to compare apples-to-apples
Set<String> runtime = new HashSet<>(tags.keySet());
runtime.addAll(metrics.config().tags().keySet());
if (!runtime.equals(expected)) {
throw new IllegalArgumentException("Tag mismatch for " + template.name() + ": runtime=" + runtime + " template=" + expected);
}
metrics.metricInstance(template, tags); Type guard
// Narrow to tag-set-equality before invoking metricInstance.
boolean tagsMatchTemplate(Metrics metrics, MetricNameTemplate t, Map<String,String> tags) {
Set<String> runtime = new HashSet<>(tags.keySet());
runtime.addAll(metrics.config().tags().keySet());
return runtime.equals(t.tags());
} Try / catch
try {
MetricName mn = metrics.metricInstance(template, tags);
} catch (IllegalArgumentException e) {
// recompute tag set from template.tags() and retry once.
} Prevention
- Always derive runtime tag keys from template.tags() rather than hardcoding them.
- Account for MetricConfig.tags() — they are merged in and can cause mismatches.
- Keep tag keys stable across versions; adding a template tag without updating callers breaks metricInstance.
- Write a small helper that builds tags from a template + value map to avoid drift.
When it happens
Trigger: Calling metrics.metricInstance(template, "k1", "v1", "k2", "v2") where the template declares a different key set (e.g. {k1,k3}). The check at Metrics.java:676 throws IllegalArgumentException listing both the runtime and template key sets so the mismatch is visible.
Common situations: Adding a new tag to a MetricNameTemplate but forgetting to update every call site that builds a metric from it (or vice versa). Removing a tag from the template while leaving legacy callers passing it. Relying on MetricConfig.tags() to supply some keys but then changing which keys are global vs per-call. Refactoring metric tag schemas across versions without updating all producers of that metric.
Related errors
- The number of samples must be at least 1.
- mBean '{mBeanName}' attribute '{templateName}' is defined tw
- keyValue needs to be specified in pairs
- Cannot use {tagName} as a tag name
- Must specify at least one metric name
AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03).
Data as JSON: /data/errors/980cd31f4617bf99.json.
Report an issue: GitHub.