apache/pulsar · error · java.lang.RuntimeException
Entry filter `${name}` cannot be loaded, see the broker logs
Error message
Entry filter `${name}` cannot be loaded, see the broker logs for further details What it means
After resolving the filter definition, load() obtains a NarClassLoader for the archive path. If getNarClassLoader returns null (the archive could not be opened/loaded; details are logged), the provider throws a RuntimeException pointing the user to broker logs.
Source
Thrown at pulsar-broker/src/main/java/org/apache/pulsar/broker/service/plugin/EntryFilterProvider.java:197
}
return ObjectMapperFactory.getYamlMapper().reader().readValue(
configStr, EntryFilterDefinition.class
);
}
@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)View on GitHub (pinned to 820761864e)
Solutions
- Check broker logs at ERROR level for the underlying NAR load failure
- Confirm the archive file exists and is readable at metadata.getArchivePath() on this broker
- Redeploy the NAR to the entryFiltersDirectory and restart the broker
Example fix
// before NAR missing: /pulsar/entryfilters/ (empty directory) // after cp audit-filter.nar /pulsar/entryfilters/ && chown pulsar:pulsar /pulsar/entryfilters/audit-filter.nar && restart broker
Defensive patterns
Strategy: try-catch
Validate before calling
Path archive = Path.of(metadata.getArchivePath());
if (!Files.isRegularFile(archive) || !Files.isReadable(archive)) {
throw new IllegalStateException("Filter NAR missing/unreadable: " + archive);
} Try / catch
try {
EntryFilter f = provider.load(metadata);
} catch (RuntimeException e) {
log.error("NAR load failed for {}; inspect broker logs for the root cause", metadata.getArchivePath(), e);
} Prevention
- Verify NAR presence/readability in the entryFiltersDirectory after each deploy
- Mount the NAR volume in containerized brokers
- Watch broker ERROR logs at startup for NAR classloader failures
When it happens
Trigger: load() called with metadata whose archivePath is null, nonexistent, unreadable, or whose NAR failed classloader construction.
Common situations: NAR file deleted or moved after policy set; wrong permissions on the entryFilters directory; broker running in container without the NAR volume mounted; corrupted NAR upload.
Related errors
- No entry filter is found for name `${filterName}`. Available
- Entry filter `${name}` does NOT provide a entry filters impl
- Class ${entryFilterClass} does not implement entry filter in
- Entry filter '${filterName}' not found
- Function class %s must be in class path
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/1d438f8b3462e58f.
Report an issue: GitHub.