apache/pulsar · error · IOException
Class ${entryFilterClass} does not implement entry filter in
Error message
Class ${entryFilterClass} does not implement entry filter interface What it means
load() instantiates the configured class via reflection and verifies it implements the EntryFilter interface before wrapping it in EntryFilterWithClassLoader. If the class instantiates but is not an EntryFilter, an IOException is thrown naming the offending class.
Source
Thrown at pulsar-broker/src/main/java/org/apache/pulsar/broker/service/plugin/EntryFilterProvider.java:203
@SuppressWarnings("unchecked")
protected EntryFilter load(EntryFilterMetaData metadata)
throws IOException {
final EntryFilterDefinition def = metadata.getDefinition();
if (StringUtils.isBlank(def.getEntryFilterClass())) {
throw new RuntimeException("Entry filter `" + def.getName() + "` does NOT provide a entry"
+ " filters implementation");
}
try {
final NarClassLoader ncl = getNarClassLoader(metadata.getArchivePath());
if (ncl == null) {
throw new RuntimeException("Entry filter `" + def.getName() + "` cannot be loaded, "
+ "see the broker logs for further details");
}
Class entryFilterClass = ncl.loadClass(def.getEntryFilterClass());
Object filter = entryFilterClass.getDeclaredConstructor().newInstance();
if (!(filter instanceof EntryFilter)) {
throw new IOException("Class " + def.getEntryFilterClass()
+ " does not implement entry filter interface");
}
EntryFilter pi = (EntryFilter) filter;
// the classloader is shared with the broker, the instance doesn't own it
return new EntryFilterWithClassLoader(pi, ncl, false);
} catch (Throwable e) {
if (e instanceof IOException) {
throw (IOException) e;
}
log.error()
.attr("entryFilterClass", metadata.getDefinition().getEntryFilterClass())
.exception(e)
.log("Failed to load class");
throw new IOException(e);
}
}
private NarClassLoader getNarClassLoader(Path archivePath) {View on GitHub (pinned to 820761864e)
Solutions
- Set entryFilterClass to a class that directly implements EntryFilter and rebuild the NAR
- Verify the interface package/name matches the broker's EntryFilter version
- Compile the filter against the same Pulsar version as the running broker
Example fix
// before
public class AuditEntryFilter { /* no interface */ }
// after
public class AuditEntryFilter implements org.apache.pulsar.broker.service.plugin.EntryFilter { ... } Defensive patterns
Strategy: validation
Validate before calling
Class<?> c = ncl.loadClass(def.getEntryFilterClass());
if (!org.apache.pulsar.broker.service.plugin.EntryFilter.class.isAssignableFrom(c)) {
throw new IllegalStateException(def.getEntryFilterClass() + " does not implement EntryFilter");
} Type guard
boolean isEntryFilterClass(String className, NarClassLoader ncl) {
try { return EntryFilter.class.isAssignableFrom(ncl.loadClass(className)); }
catch (ClassNotFoundException e) { return false; }
} Try / catch
try {
EntryFilter f = provider.load(metadata);
} catch (IOException e) {
log.error("{} does not implement EntryFilter; fix the definition or the class", e.getMessage());
} Prevention
- Compile filter NARs against the broker's Pulsar version
- Add a unit test asserting the configured class implements EntryFilter
- Never point entryFilterClass at helper/abstract classes
When it happens
Trigger: entryFilterClass in the filter definition points to a valid class that does not implement org.apache.pulsar.broker.service.plugin.EntryFilter (wrong class name, wrong version of the class, or a helper class referenced by mistake).
Common situations: Definition written against an old interface/package that changed between Pulsar versions; copy-pasted class name from another plugin type (e.g. a BrokerEntryMetadataFilter); class compiled against a different EntryFilter interface so instanceof fails.
Related errors
- No entry filter is found for name `${filterName}`. Available
- Entry filter `${name}` does NOT provide a entry filters impl
- Entry filter `${name}` cannot be loaded, see the broker logs
- Entry filter '${filterName}' not found
- Class ${className} does not implement additional servlet int
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/c258bee219eeac20.
Report an issue: GitHub.