apache/pulsar · error · RuntimeException
(wraps ClassNotFoundException for BrokerEntryMetadataInterce
Error message
(wraps ClassNotFoundException for BrokerEntryMetadataInterceptor)
What it means
In loadBrokerEntryMetadataInterceptors, if the interceptor class named in configuration cannot be found on the classpath, ClassNotFoundException is logged and wrapped in a RuntimeException and broker startup/usage fails.
Source
Thrown at pulsar-common/src/main/java/org/apache/pulsar/common/intercept/BrokerEntryMetadataUtils.java:58
@SuppressWarnings("unchecked") // class is loaded by name and expected to implement the interface
Class<BrokerEntryMetadataInterceptor> clz = (Class<BrokerEntryMetadataInterceptor>) ClassLoaderUtils
.loadClass(interceptorName, classLoader);
try {
interceptors.add(clz.getDeclaredConstructor().newInstance());
} catch (InstantiationException | IllegalAccessException
| InvocationTargetException | NoSuchMethodException e) {
log.error()
.attr("interceptorName", interceptorName)
.exception(e)
.log("Create new BrokerEntryMetadataInterceptor instance failed.");
throw new RuntimeException(e);
}
} catch (ClassNotFoundException e) {
log.error()
.attr("interceptorName", interceptorName)
.exception(e)
.log("Load BrokerEntryMetadataInterceptor class failed.");
throw new RuntimeException(e);
}
}
}
return interceptors;
}
public static <T> Set<T> loadInterceptors(
Set<String> interceptorNames, ClassLoader classLoader) {
Set<T> interceptors = new LinkedHashSet<>();
if (interceptorNames != null && interceptorNames.size() > 0) {
for (String interceptorName : interceptorNames) {
try {
@SuppressWarnings("unchecked") // class is loaded by name and expected to match type T
Class<T> clz = (Class<T>) ClassLoaderUtils
.loadClass(interceptorName, classLoader);
try {
interceptors.add(clz.getDeclaredConstructor().newInstance());
} catch (InstantiationException | IllegalAccessException
| InvocationTargetException | NoSuchMethodException e) {View on GitHub (pinned to 820761864e)
Solutions
- Correct the class name in brokerEntryMetadataInterceptors to match the actual fully-qualified class
- Install the jar containing the interceptor into the broker classpath (e.g. lib/ or plugins directory)
- Confirm with the broker log line 'Load BrokerEntryMetadataInterceptor class failed.' which name failed
Example fix
// before brokerEntryMetadataInterceptors=org.example.MyEntryMetaInterceptor // jar missing // after brokerEntryMetadataInterceptors=org.example.entrymeta.MyEntryMetaInterceptor // corrected FQCN, jar installed
Defensive patterns
Strategy: validation
Validate before calling
try {
Class.forName(configuredInterceptorName);
} catch (ClassNotFoundException e) {
throw new IllegalStateException("Interceptor class not on broker classpath: " + configuredInterceptorName);
} Try / catch
try {
interceptors = BrokerEntryMetadataUtils.loadBrokerEntryMetadataInterceptors(names, conf);
} catch (RuntimeException e) {
if (e.getCause() instanceof ClassNotFoundException) {
throw new IllegalStateException("Install the jar containing " + e.getCause().getMessage(), e);
}
throw e;
} Prevention
- Use fully-qualified class names copied from the interceptor source, not hand-typed
- Deploy plugin jars to every broker in the cluster, not just one
- Verify classpath contents after broker upgrades (class renames happen)
When it happens
Trigger: brokerEntryMetadataInterceptors contains a fully-qualified class name that is not present on the broker's classpath (misspelled name, missing jar, wrong package).
Common situations: Custom interceptor plugin jar not copied to the broker's lib directory, class renamed in an upgrade, fat-fingered config value in broker.conf.
Related errors
- (wraps reflective instantiation failure for BrokerEntryMetad
- (wraps ClassNotFoundException for interceptor)
- User class must be in class path
- Class must be in class path
- Failed to load an authorization provider.
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/6680ff88d1ba0b6b.
Report an issue: GitHub.