{"id":"a3cd4d01e9de1632","repo":"apache/kafka","slug":"unknown-metric-metricname","errorCode":null,"errorMessage":"Unknown metric {metricName}","messagePattern":"Unknown metric (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"clients/src/main/java/org/apache/kafka/common/metrics/internals/PluginMetricsImpl.java","lineNumber":77,"sourceCode":"\n    @Override\n    public void addMetric(MetricName metricName, MetricValueProvider<?> metricValueProvider) {\n        if (closing) throw new IllegalStateException(\"This PluginMetrics instance is closed\");\n        if (metricNames.contains(metricName)) {\n            throw new IllegalArgumentException(\"Metric \" + metricName + \" already exists\");\n        }\n        metrics.addMetric(metricName, metricValueProvider);\n        metricNames.add(metricName);\n    }\n\n    @Override\n    public void removeMetric(MetricName metricName) {\n        if (closing) throw new IllegalStateException(\"This PluginMetrics instance is closed\");\n        if (metricNames.contains(metricName)) {\n            metrics.removeMetric(metricName);\n            metricNames.remove(metricName);\n        } else {\n            throw new IllegalArgumentException(\"Unknown metric \" + metricName);\n        }\n    }\n\n    @Override\n    public Sensor addSensor(String name) {\n        if (closing) throw new IllegalStateException(\"This PluginMetrics instance is closed\");\n        if (sensors.contains(name)) {\n            throw new IllegalArgumentException(\"Sensor \" + name + \" already exists\");\n        }\n        Sensor sensor = metrics.sensor(name);\n        sensors.add(name);\n        return sensor;\n    }\n\n    @Override\n    public void removeSensor(String name) {\n        if (closing) throw new IllegalStateException(\"This PluginMetrics instance is closed\");\n        if (sensors.contains(name)) {","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/apache/kafka/blob/c31c9215e131f8c17e79f8901b48c13ee6aa8e7a/clients/src/main/java/org/apache/kafka/common/metrics/internals/PluginMetricsImpl.java#L59-L95","documentation":"Thrown by PluginMetricsImpl.removeMetric when the supplied MetricName is not in the per-instance 'metricNames' set, i.e. the metric was never added through this PluginMetrics handle (or was already removed). The implementation is strict: you can only remove what you added via the same handle's addMetric. Attempting to remove a metric registered elsewhere, or removing the same name twice, is rejected.","triggerScenarios":"Calling pluginMetrics.removeMetric(name) for a name that was added via metrics.addMetric directly, via a different PluginMetrics instance, or that has already been removed. Also triggered by passing a MetricName whose group/tags differ from the one returned by pluginMetrics.metricName(...) (MetricName equality includes group and tags).","commonSituations":"A plugin that registers metrics with the global Metrics object instead of the provided PluginMetrics handle and then tries to clean them up through the handle; double-cleanup in stop(); copy-paste of MetricName construction that yields a name equal by display string but not by the cached MetricName object's identity.","solutions":["Only remove metrics you added via the same pluginMetrics.addMetric(name, provider) call; track them in a field if needed.","Verify the MetricName passed to removeMetric is exactly the object returned by pluginMetrics.metricName(...) — same group, name, and tags.","If you registered the metric through the raw Metrics object instead of PluginMetrics, remove it through metrics.removeMetric(...) (or just let PluginMetrics.close() manage lifecycle)."],"exampleFix":"// before\nmetrics.addMetric(name, provider);          // registered on global Metrics\n...\npluginMetrics.removeMetric(name);            // Unknown metric\n// after\npluginMetrics.addMetric(name, provider);     // registered on the handle\n...\npluginMetrics.removeMetric(name);            // ok","handlingStrategy":"validation","validationCode":"// Maintain a Set<MetricName> of metrics YOU registered with this PluginMetrics instance.\nprivate final Set<MetricName> registered = ConcurrentHashMap.newKeySet();\n// On addMetric: registered.add(name);\n// Before removeMetric:\nif (metricName == null || !registered.remove(metricName)) {\n    return; // not registered here, nothing to remove\n}\npluginMetrics.removeMetric(metricName);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always track the MetricName objects you registered in your own collection rather than relying on the library to remember.","Guard removeMetric with a contains-check on your own registry; never call removeMetric speculatively.","Make cleanup idempotent: remove from your set first, and only call the library if removal succeeded.","Remember MetricName equality is by value (name+group+tags), so the same logical metric removed twice will trigger this error."],"tags":["metrics","plugin-lifecycle","api-misuse"],"analyzedSha":"c31c9215e131f8c17e79f8901b48c13ee6aa8e7a","analyzedAt":"2026-08-03T12:34:05.770Z","schemaVersion":2}