{"id":"f4e9a28170889347","repo":"apache/kafka","slug":"error-creating-mbean-attribute-for-metricname-me","errorCode":null,"errorMessage":"Error creating mbean attribute for metricName :{metricName}","messagePattern":"Error creating mbean attribute for metricName :(.+?)","errorType":"exception","errorClass":"KafkaException","httpStatus":null,"severity":"error","filePath":"clients/src/main/java/org/apache/kafka/common/metrics/JmxReporter.java","lineNumber":170,"sourceCode":"    private KafkaMbean removeAttribute(KafkaMetric metric, String mBeanName) {\n        MetricName metricName = metric.metricName();\n        KafkaMbean mbean = this.mbeans.get(mBeanName);\n        if (mbean != null)\n            mbean.removeAttribute(metricName.name());\n        return mbean;\n    }\n\n    private String addAttribute(KafkaMetric metric) {\n        try {\n            MetricName metricName = metric.metricName();\n            String mBeanName = getMBeanName(prefix, metricName);\n            if (!this.mbeans.containsKey(mBeanName))\n                mbeans.put(mBeanName, new KafkaMbean(mBeanName));\n            KafkaMbean mbean = this.mbeans.get(mBeanName);\n            mbean.setAttribute(metricName.name(), metric);\n            return mBeanName;\n        } catch (JMException e) {\n            throw new KafkaException(\"Error creating mbean attribute for metricName :\" + metric.metricName(), e);\n        }\n    }\n\n    /**\n     * @param metricName\n     * @return standard JMX MBean name in the following format domainName:type=metricType,key1=val1,key2=val2\n     */\n    static String getMBeanName(String prefix, MetricName metricName) {\n        StringBuilder mBeanName = new StringBuilder();\n        mBeanName.append(prefix);\n        mBeanName.append(\":type=\");\n        mBeanName.append(metricName.group());\n        for (Map.Entry<String, String> entry : metricName.tags().entrySet()) {\n            if (entry.getKey().isEmpty() || entry.getValue().isEmpty())\n                continue;\n            mBeanName.append(\",\");\n            mBeanName.append(entry.getKey());\n            mBeanName.append(\"=\");","sourceCodeStart":152,"sourceCodeEnd":188,"githubUrl":"https://github.com/apache/kafka/blob/c31c9215e131f8c17e79f8901b48c13ee6aa8e7a/clients/src/main/java/org/apache/kafka/common/metrics/JmxReporter.java#L152-L188","documentation":"Thrown by JmxReporter.addAttribute(KafkaMetric) when constructing or registering a JMX attribute for a metric fails with a JMException (e.g. MalformedObjectNameException, the metric name produced an invalid ObjectName, or the attribute could not be associated). Kafka wraps the cause in a KafkaException so metric-reporting failures during metric registration are not silently lost. The message includes the full metricName so the offending metric is identifiable.","triggerScenarios":"A new KafkaMetric is added to a Metrics instance that has JmxReporter installed; addAttribute() builds the mbean name via getMBeanName() and calls KafkaMbean.setAttribute(); if KafkaMbean's ObjectName construction throws or setAttribute encounters a JMException, the exception propagates here and is rethrown. Triggered by AdminClient/KafkaProducer/KafkaConsumer/KafkaStreams construction (or first metric add) when JMX metrics are enabled (default).","commonSituations":"A metric group or tag value contains characters that break JMX ObjectName syntax despite the Sanitizer.jmxSanitize() pass (e.g. extremely long values, reserved domain fragments); a custom Sensor added with a name colliding with an existing mbean in a different domain; running in a container/JVM that restricts JMX (SecurityManager / limited platform MBean server); JMX port/domain misconfiguration via `com.sun.management.jmxremote.*` system properties; a plugin registering metrics with weird tags.","solutions":["Read the attached JMException cause — it specifies whether the failure is a malformed name, a duplicate, or an MBean-server rejection.","Inspect the metricName in the message: if a tag value is the culprit, sanitize or rename the tag at the point you create the Sensor/MetricName.","If you do not need JMX, disable the JmxReporter (don't add it to Metrics, or set auto-generated JMX domain to a non-conflicting value) so metric registration no longer touches the MBean server.","If JMX is required, ensure your JMX domain prefix and metric group/tag values are short, ASCII, and free of characters the Sanitizer does not escape.","Check the runtime env: confirm the process has permission to register mbeans (no restrictive SecurityManager / JMX auth misconfiguration) and that another process has not already registered a clashing ObjectName."],"exampleFix":"// before — metric tag with a value that breaks JMX\nMetricName name = metrics.metricName(\"queue-size\", \"app\",\n    Map.of(\"path\", tenantPath));           // e.g. \"orders/eu-west-1\"\nmetrics.addMetric(name, (c, now) -> queue.size());   // JmxReporter.addAttribute throws\n\n// after — sanitize tag values before building the metric\nString safePath = tenantPath.replaceAll(\"[^a-zA-Z0-9._-]\", \"_\");\nMetricName name = metrics.metricName(\"queue-size\", \"app\",\n    Map.of(\"path\", safePath));\nmetrics.addMetric(name, (c, now) -> queue.size());","handlingStrategy":"try-catch","validationCode":"// No API exists to pre-flight a single metric; instead keep metric names and tags JMX-safe.\n// Ensure MetricName.group(), tags keys/values are non-null and ASCII-safe.\nMetricName name = new MetricName(\"records\", \"my-group\", \"desc\", Map.of(\"client-id\", clientId));\nassert name.group().matches(\"[a-zA-Z0-9._-]+\") : \"group must be JMX-safe\";\nassert !name.tags().containsValue(null) : \"null tag values break JMX\";","typeGuard":"// Reject metric names whose group/tags would produce a malformed ObjectName.\nstatic boolean isJmxSafe(MetricName n) {\n    if (n.group() == null || n.group().isEmpty()) return false;\n    for (var e : n.tags().entrySet()) {\n        if (e.getKey() == null || e.getValue() == null) return false;\n        if (e.getKey().contains(\",\") || e.getKey().contains(\":\") || e.getKey().contains(\"=\")) return false;\n    }\n    return true;\n}","tryCatchPattern":"try {\n    metrics.addMetric(metricName, measurable);\n} catch (KafkaException e) {\n    // JmxReporter chains the JMException as cause; degrade by disabling JMX rather than crashing.\n    if (e.getCause() instanceof JMException) {\n        log.error(\"JMX registration failed for {}; disabling JMX reporter\", metricName, e.getCause());\n        disableJmxReporter();\n    } else {\n        throw e;\n    }\n}","preventionTips":["Keep metric group/name/tags ASCII and free of ':', ',', '=', '*' — these break ObjectName construction.","Sanitize tag values (e.g. client-id) before placing them in MetricName; JmxReporter does jmxSanitize but only on values, not keys.","If JMX is optional in your deployment, run JmxReporter behind a flag so a JMX failure cannot abort application startup.","Inspect the chained JMException (MalformedObjectNameException is the most common) to find the offending character."],"tags":["kafka-clients","jmx","metrics","jmx-reporter","startup"],"analyzedSha":"c31c9215e131f8c17e79f8901b48c13ee6aa8e7a","analyzedAt":"2026-08-03T12:34:05.770Z","schemaVersion":2}