{"id":"2c70733b1f6e3643","repo":"apache/kafka","slug":"mbean-mbeanname-attribute-templatename-is","errorCode":null,"errorMessage":"mBean '{mBeanName}' attribute '{templateName}' is defined twice.","messagePattern":"mBean '(.+?)' attribute '(.+?)' is defined twice\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"clients/src/main/java/org/apache/kafka/common/metrics/Metrics.java","lineNumber":285,"sourceCode":"        Map<String, Map<String, String>> beansAndAttributes = new TreeMap<>();\n    \n        try (Metrics metrics = new Metrics()) {\n            for (MetricNameTemplate template : allMetrics) {\n                Map<String, String> tags = new LinkedHashMap<>();\n                for (String s : template.tags()) {\n                    tags.put(s, \"{\" + s + \"}\");\n                }\n    \n                MetricName metricName = metrics.metricName(template.name(), template.group(), template.description(), tags);\n                String mBeanName = JmxReporter.getMBeanName(domain, metricName);\n                if (!beansAndAttributes.containsKey(mBeanName)) {\n                    beansAndAttributes.put(mBeanName, new TreeMap<>());\n                }\n                Map<String, String> attrAndDesc = beansAndAttributes.get(mBeanName);\n                if (!attrAndDesc.containsKey(template.name())) {\n                    attrAndDesc.put(template.name(), template.description());\n                } else {\n                    throw new IllegalArgumentException(\"mBean '\" + mBeanName + \"' attribute '\" + template.name() + \"' is defined twice.\");\n                }\n            }\n        }\n        StringBuilder b = new StringBuilder();\n        b.append(\"<table class=\\\"data-table\\\">\\n<tbody>\\n\");\n        b.append(\"<tr>\\n\");\n        b.append(\"<th>Metric/Attribute name</th>\\n\");\n        b.append(\"<th>Description</th>\\n\");\n        b.append(\"<th>Mbean name</th>\\n\");\n        b.append(\"</tr>\\n\");\n        for (Entry<String, Map<String, String>> e : beansAndAttributes.entrySet()) {\n            for (Entry<String, String> e2 : e.getValue().entrySet()) {\n                b.append(\"<tr>\\n\");\n                b.append(\"<td>\");\n                b.append(e2.getKey());\n                b.append(\"</td>\\n\");\n                b.append(\"<td>\");\n                b.append(e2.getValue());","sourceCodeStart":267,"sourceCodeEnd":303,"githubUrl":"https://github.com/apache/kafka/blob/c31c9215e131f8c17e79f8901b48c13ee6aa8e7a/clients/src/main/java/org/apache/kafka/common/metrics/Metrics.java#L267-L303","documentation":"Thrown by Metrics.toHtmlTable while generating the public metrics documentation table. For each MetricNameTemplate it builds a stable mBean name from (domain, group, name, tags); if two distinct templates resolve to the same mBean name AND the same attribute (template.name), the second one is rejected, because the generated HTML table and the documented MBean attribute set would otherwise be ambiguous.","triggerScenarios":"Calling Metrics.toHtmlTable(domain, templates) where the iterable contains two MetricNameTemplate objects with identical name and group/tags that produce the same mBean string. Typically hit by code that aggregates templates from multiple modules and accidentally includes a duplicate, or by a template whose tags were changed such that two templates now collapse onto the same MBean.","commonSituations":"Maintainers regenerating the metrics documentation table after adding a new metric that reuses an existing name. Merging metric templates from two modules without deduplication. Editing a MetricNameTemplate's tags so its mBean collides with a sibling template. Running the docs generation across a broader classpath than intended.","solutions":["Inspect the templates passed to toHtmlTable and remove the duplicate MetricNameTemplate (same name + tags).","If both metrics are legitimate, differentiate them by group, name, or tags so they map to distinct mBean names.","Build the template list from a single canonical source (e.g. one constants class per module) to prevent cross-module duplicates.","Re-run the docs/table generation; the error message names the colliding mBean and attribute."],"exampleFix":"// before: List.of(recordSendRateTemplate, recordSendRateTemplate /* duplicate */)\n// after:  List.of(recordSendRateTemplate, recordRetryRateTemplate)","handlingStrategy":"validation","validationCode":"// Before adding a metric/template, ensure (group, name) is unique within the same mBean.\nSet<String> seen = new HashSet<>();\nfor (MetricNameTemplate t : templates) {\n    String key = t.group() + \":\" + t.name();\n    if (!seen.add(key)) {\n        throw new IllegalStateException(\"Duplicate metric name in group: \" + key);\n    }\n}","typeGuard":"// Ensure template name uniqueness per group to avoid mBean attribute collisions.\nboolean isUniqueTemplate(List<MetricNameTemplate> templates) {\n    Set<String> keys = new HashSet<>();\n    for (MetricNameTemplate t : templates) if (!keys.add(t.group() + \":\" + t.name())) return false;\n    return true;\n}","tryCatchPattern":"try {\n    metrics.addMetric(name, provider);\n} catch (IllegalArgumentException e) {\n    // duplicate mBean attribute; rename or skip registration.\n}","preventionTips":["Metric attribute names must be unique within the same mBean (group+tags); reuse names only across disjoint groups.","When templating metrics, audit the (name, group, tags) tuple for collisions at build time.","Avoid giving two sensors metrics with identical names in the same group.","Run a preflight that builds all MetricNames and checks for duplicates."],"tags":["metrics","metric-name-template","docs-generation","duplicate"],"analyzedSha":"c31c9215e131f8c17e79f8901b48c13ee6aa8e7a","analyzedAt":"2026-08-03T12:34:05.770Z","schemaVersion":2}