apache/hadoop · error · MetricsConfigException
Error creating plugin: {}
Error message
Error creating plugin: {} What it means
MetricsConfig.getPlugin reflectively instantiates every metrics2 source/sink/filter named by a *.class property in hadoop-metrics2.properties: Class.forName with the plugin classloader, newInstance(), then plugin.init(subsetConfig). Any failure — class not found, no accessible no-arg constructor, ClassCastException to MetricsPlugin, or an exception thrown inside init() — is wrapped in MetricsConfigException('Error creating plugin: <className>') with the original cause attached. It surfaces during MetricsSystem init, typically at daemon startup or first metrics use.
Source
Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/metrics2/impl/MetricsConfig.java:210
: PREFIX_DEFAULT + key);
}
LOG.debug("Returning '{}' for key: {}", value, key);
return value;
}
<T extends MetricsPlugin> T getPlugin(String name) {
String clsName = getClassName(name);
if (clsName == null) {
return null;
}
try {
Class<?> cls = Class.forName(clsName, true, getPluginLoader());
@SuppressWarnings("unchecked")
T plugin = (T) cls.newInstance();
plugin.init(name.isEmpty() ? this : subset(name));
return plugin;
} catch (Exception e) {
throw new MetricsConfigException("Error creating plugin: "+ clsName, e);
}
}
String getClassName(String prefix) {
String classKey = prefix.isEmpty() ? "class" : prefix.concat(".class");
String clsName = getString(classKey);
LOG.debug("Class name for prefix {} is {}", prefix, clsName);
if (clsName == null || clsName.isEmpty()) {
return null;
}
return clsName;
}
ClassLoader getPluginLoader() {
if (pluginLoader != null) {
return pluginLoader;
}
final ClassLoader defaultLoader = getClass().getClassLoader();View on GitHub (pinned to 2add963021)
Solutions
- Read the nested cause first (getCause()) — it distinguishes ClassNotFoundException vs InstantiationException vs init() failure and points at the real fix.
- Verify the class name spelling and that the jar is on the daemon's classpath (put it in HADOOP_COMMON_LIB_NATIVE or the service lib dir) with a public no-arg constructor implementing the right MetricsPlugin interface.
- Fix the plugin's own config subset (its sink/source properties) if the cause is an init() exception.
- As a stopgap, comment out the offending *.class property to restore metrics startup, then redeploy the fixed plugin.
Example fix
# before *.sink.graph.class=com.example.GraphiteSink # jar missing on nodes # after cp graphite-metrics-sink.jar $HADOOP_HOME/share/hadoop/common/lib/ # or, to restore startup immediately: # *.sink.graph.class=org.apache.hadoop.metrics2.sink.FileSink # *.sink.graph.filename=/tmp/metrics.out
Defensive patterns
Strategy: try-catch
Validate before calling
// Smoke-test a configured plugin class before trusting it in production
String clsName = metricsConf.getString("sink.custom.class");
Class<?> c = Class.forName(clsName, true, pluginClassLoader);
if (!org.apache.hadoop.metrics2.MetricsSink.class.isAssignableFrom(c)
&& !org.apache.hadoop.metrics2.MetricsSource.class.isAssignableFrom(c)) {
throw new IllegalArgumentException(clsName + " implements neither MetricsSink nor MetricsSource");
}
c.getConstructor(); // fails fast without a public no-arg ctor Try / catch
try {
MetricsSource src = conf.getPlugin("source.custom");
} catch (MetricsConfigException mce) {
Throwable root = mce.getCause() != null ? mce.getCause() : mce;
LOG.error("metrics2 plugin failed to load: {} (cause: {})",
mce.getMessage(), root.toString());
// decide: fall back to a stock sink or abort startup with a clear message
} Prevention
- Always inspect getCause() of MetricsConfigException — it distinguishes missing jar, bad constructor, and init-config errors.
- Deploy custom metrics plugin jars to every daemon and verify with 'hadoop classpath' before enabling the .class property.
- Require a public no-arg constructor and the correct MetricsPlugin interface in plugin code reviews.
- Keep a known-good fallback sink config (e.g., FileSink) commented in hadoop-metrics2.properties for quick recovery.
When it happens
Trigger: *.sink.custom.class=com.example.MySink where the jar is absent from the daemon classpath; class lacks a public no-arg constructor; class does not implement MetricsSink/MetricsSource; plugin.init() throws because its own config subset is incomplete (e.g., FileSink without a filename).
Common situations: Deploying custom metrics sinks (Graphite/Kafka/Prometheus writers) and forgetting the jar or shading it wrongly; typo in the class property; version upgrades renaming plugin classes; sink-specific properties missing after config migration.
Related errors
- Failed to create Store Operations from configuration option
- No KeyProviderFactory for ${uri} in ${KEY_PROVIDER_PATH}
- Could not find configured fencing method {}
- Class {} does not implement FenceMethod
- Cannot initialize the class: {clazz}
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/4c7a85c652732438.
Report an issue: GitHub.