apache/pulsar · error · IOException
Class ${handlerClass} does not implement protocol handler in
Error message
Class ${handlerClass} does not implement protocol handler interface What it means
Thrown by ProtocolHandlerUtils.load after the handler class is instantiated but the resulting object is not an instance of ProtocolHandler. The NAR declared a handlerClass, but that class does not implement the required interface, so the broker rejects it.
Source
Thrown at pulsar-broker/src/main/java/org/apache/pulsar/broker/protocol/ProtocolHandlerUtils.java:140
String narExtractionDirectory) throws IOException {
final File narFile = metadata.getArchivePath().toAbsolutePath().normalize().toFile();
NarClassLoader ncl = NarClassLoaderBuilder.builder()
.narFile(narFile)
.parentClassLoader(ProtocolHandler.class.getClassLoader())
.extractionDirectory(narExtractionDirectory)
.build();
ProtocolHandlerDefinition phDef = getProtocolHandlerDefinition(ncl);
if (StringUtils.isBlank(phDef.getHandlerClass())) {
throw new IOException("Protocol handler `" + phDef.getName() + "` does NOT provide a protocol"
+ " handler implementation");
}
try {
Class handlerClass = ncl.loadClass(phDef.getHandlerClass());
Object handler = handlerClass.getDeclaredConstructor().newInstance();
if (!(handler instanceof ProtocolHandler)) {
throw new IOException("Class " + phDef.getHandlerClass()
+ " does not implement protocol handler interface");
}
ProtocolHandler ph = (ProtocolHandler) handler;
return new ProtocolHandlerWithClassLoader(ph, ncl);
} catch (Throwable t) {
rethrowIOException(t);
return null;
}
}
private static void rethrowIOException(Throwable cause)
throws IOException {
if (cause instanceof IOException) {
throw (IOException) cause;
} else if (cause instanceof RuntimeException) {
throw (RuntimeException) cause;
} else if (cause instanceof Error) {
throw (Error) cause;View on GitHub (pinned to 820761864e)
Solutions
- Make the declared handlerClass implement org.apache.pulsar.broker.protocol.ProtocolHandler and rebuild the NAR.
- Ensure the handler implements the ProtocolHandler interface from the SAME Pulsar version as the broker (compile against matching pulsar-broker/pulsar-common versions).
- Check that the handlerClass in the NAR definition points at the handler class, not a supporting class.
- Avoid shading conflicting copies of the ProtocolHandler interface into your NAR.
Example fix
// before
public class KafkaProtocolHandler { /* no interface */ }
// after
public class KafkaProtocolHandler implements ProtocolHandler {
public void initialize(ProtocolHandlerData ... ) { ... }
...
} Defensive patterns
Strategy: validation
Validate before calling
// Verify the class implements ProtocolHandler before packaging
class Check {
public static void main(String[] a) throws Exception {
Class<?> c = Class.forName(a[0]);
if (!org.apache.pulsar.broker.protocol.ProtocolHandler.class.isAssignableFrom(c))
throw new IllegalStateException(a[0] + " does not implement ProtocolHandler");
}
} Try / catch
try {
handler = ProtocolHandlerUtils.load(definition, narDir);
} catch (IOException e) {
if (e.getMessage() != null && e.getMessage().contains("does not implement protocol handler interface")) {
log.error("Declared handlerClass must implement ProtocolHandler");
}
throw e;
} Prevention
- Compile the handler against the same Pulsar version as the broker
- Add an instanceof/assignability unit test for the declared handler class
- Do not shade the ProtocolHandler interface into your NAR
- Point handlerClass at the handler itself, not a helper class
When it happens
Trigger: ProtocolHandlerUtils.load loads phDef.getHandlerClass() and calls newInstance(); the created object fails the `instanceof ProtocolHandler` check.
Common situations: Pointing handlerClass at a helper/config class instead of the handler; a class implementing a ProtocolHandler from an incompatible Pulsar version loaded on a different classloader; refactoring renamed/moved the interface so the class no longer implements it.
Related errors
- Protocol handler `${name}` does NOT provide a protocol handl
- Failed to load the protocol handler for protocol `${protocol
- No protocol handler is found for protocol `${protocol}`. Ava
- Malformed protocol handler found for protocol `${protocol}`
- Protocol handler for `${handler}` attempts to use ${address}
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/4478284cdb984150.
Report an issue: GitHub.