apache/kafka · warning · KafkaException
Error unregistering mbean
Error message
Error unregistering mbean
What it means
Thrown by JmxReporter.unregister(KafkaMbean) when MBeanServer.unregisterMBean() raises a JMException (most often InstanceNotFoundException) for an mbean the reporter believed was registered. Kafka treats this as an error during teardown so that silent metric leaks (mbeans never cleaned up) are visible rather than hidden. The cause carries the original JMException.
Source
Thrown at clients/src/main/java/org/apache/kafka/common/metrics/JmxReporter.java:207
mBeanName.append(Sanitizer.jmxSanitize(entry.getValue()));
}
return mBeanName.toString();
}
public void close() {
synchronized (LOCK) {
for (KafkaMbean mbean : this.mbeans.values())
unregister(mbean);
}
}
private void unregister(KafkaMbean mbean) {
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
try {
if (server.isRegistered(mbean.name()))
server.unregisterMBean(mbean.name());
} catch (JMException e) {
throw new KafkaException("Error unregistering mbean", e);
}
}
private void reregister(KafkaMbean mbean) {
unregister(mbean);
try {
ManagementFactory.getPlatformMBeanServer().registerMBean(mbean, mbean.name());
} catch (JMException e) {
throw new KafkaException("Error registering mbean " + mbean.name(), e);
}
}
private static class KafkaMbean implements DynamicMBean {
private final ObjectName objectName;
private final Map<String, KafkaMetric> metrics;
KafkaMbean(String mbeanName) throws MalformedObjectNameException {
this.metrics = new HashMap<>();View on GitHub (pinned to c31c9215e1)
Solutions
- Read the attached JMException cause — InstanceNotFoundException indicates the mbean was already gone, which is usually benign during teardown.
- If you see this repeatedly in normal operation, ensure each Kafka client instance uses a distinct JMX domain prefix (KafkaJmxReporter / metrics namespace) so two instances never collide on the same ObjectName.
- In embedded/container deployments, stop the Kafka client before the container reaps mbeans (lifecycle ordering) so Kafka's own close() runs first.
- Suppress non-fatal teardown noise by catching KafkaException around client.close() in your shutdown hook and logging the cause rather than aborting.
- Upgrade to a current Kafka version; some unregister races under repeated client create/close have been addressed in recent releases.
Example fix
// before — teardown aborts on an already-gone mbean
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
producer.close(); // JmxReporter.unregister throws InstanceNotFoundException
}));
// after — shutdown is resilient to teardown noise
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
try { producer.close(Duration.ofSeconds(10)); }
catch (org.apache.kafka.common.KafkaException e) {
log.warn("Non-fatal error closing Kafka client / JMX reporter", e);
}
})); Defensive patterns
Strategy: try-catch
Validate before calling
// There is no pre-check; the safe pattern is to verify registration state before unregister.
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
ObjectName on = ...;
if (server.isRegistered(on)) {
server.unregisterMBean(on);
} Type guard
// Narrow 'an mbean that is currently registered' before unregistering.
static boolean isRegistered(ObjectName name) {
return ManagementFactory.getPlatformMBeanServer().isRegistered(name);
} Try / catch
try {
metrics.close(); // or metricsReporterClose()
} catch (KafkaException e) {
if (e.getCause() instanceof JMException) {
// unregister failures are typically benign during shutdown; log and continue.
log.warn("JMX mbean unregister failed; continuing shutdown", e.getCause());
} else {
throw e;
}
} Prevention
- Always close Metrics via try-with-resources; treat unregister failures as warnings, not fatal errors.
- Do not manually unregister Kafka mbeans from an external MBeanServer — let JmxReporter.close() own the lifecycle.
- If you run multiple Metrics instances in one JVM, give each a unique prefix/namespace to avoid cross-unregister races.
- Audit for code that calls platformMBeanServer.unregisterMBean on Kafka-created names; remove it.
When it happens
Trigger: JmxReporter.close() iterates all registered KafkaMbeans and calls unregister() on each; reregister() also calls unregister() before re-registering an updated mbean. If something else has already unregistered the mbean out from under Kafka, or the platform MBeanServer is in an inconsistent state, server.unregisterMBean throws and is wrapped here.
Common situations: An external JMX client or agent unregistered mbeans independently; the JVM is shutting down and platform MBeanServer is tearing down concurrently; another KafkaMetrics instance in the same JVM reused the same JMX domain and ObjectName; running under a servlet container (Tomcat/JBoss) where the container reaps mbeans on undeploy before Kafka's close runs; repeated create/close cycles of producer/consumer/AdminClient with overlapping JMX domains.
Related errors
- Error creating mbean attribute for metricName :{metricName}
- Error registering mbean {mbeanName}
- Could not find attribute {name}
- failed closing plugin
- Set not allowed.
AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03).
Data as JSON: /data/errors/ce4f2430f54dff9e.json.
Report an issue: GitHub.