{"record":{"id":"4478284cdb984150","repo":"apache/pulsar","slug":"class-handlerclass-does-not-implement-protocol","errorCode":null,"errorMessage":"Class ${handlerClass} does not implement protocol handler interface","messagePattern":"Class (.+?) does not implement protocol handler interface","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"pulsar-broker/src/main/java/org/apache/pulsar/broker/protocol/ProtocolHandlerUtils.java","lineNumber":140,"sourceCode":"                                               String narExtractionDirectory) throws IOException {\n        final File narFile = metadata.getArchivePath().toAbsolutePath().normalize().toFile();\n        NarClassLoader ncl = NarClassLoaderBuilder.builder()\n                .narFile(narFile)\n                .parentClassLoader(ProtocolHandler.class.getClassLoader())\n                .extractionDirectory(narExtractionDirectory)\n                .build();\n\n        ProtocolHandlerDefinition phDef = getProtocolHandlerDefinition(ncl);\n        if (StringUtils.isBlank(phDef.getHandlerClass())) {\n            throw new IOException(\"Protocol handler `\" + phDef.getName() + \"` does NOT provide a protocol\"\n                + \" handler implementation\");\n        }\n\n        try {\n            Class handlerClass = ncl.loadClass(phDef.getHandlerClass());\n            Object handler = handlerClass.getDeclaredConstructor().newInstance();\n            if (!(handler instanceof ProtocolHandler)) {\n                throw new IOException(\"Class \" + phDef.getHandlerClass()\n                    + \" does not implement protocol handler interface\");\n            }\n            ProtocolHandler ph = (ProtocolHandler) handler;\n            return new ProtocolHandlerWithClassLoader(ph, ncl);\n        } catch (Throwable t) {\n            rethrowIOException(t);\n            return null;\n        }\n    }\n\n    private static void rethrowIOException(Throwable cause)\n            throws IOException {\n        if (cause instanceof IOException) {\n            throw (IOException) cause;\n        } else if (cause instanceof RuntimeException) {\n            throw (RuntimeException) cause;\n        } else if (cause instanceof Error) {\n            throw (Error) cause;","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-broker/src/main/java/org/apache/pulsar/broker/protocol/ProtocolHandlerUtils.java#L122-L158","documentation":"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.","triggerScenarios":"ProtocolHandlerUtils.load loads phDef.getHandlerClass() and calls newInstance(); the created object fails the `instanceof ProtocolHandler` check.","commonSituations":"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.","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."],"exampleFix":"// before\npublic class KafkaProtocolHandler { /* no interface */ }\n// after\npublic class KafkaProtocolHandler implements ProtocolHandler {\n  public void initialize(ProtocolHandlerData ... ) { ... }\n  ...\n}","handlingStrategy":"validation","validationCode":"// Verify the class implements ProtocolHandler before packaging\nclass Check {\n  public static void main(String[] a) throws Exception {\n    Class<?> c = Class.forName(a[0]);\n    if (!org.apache.pulsar.broker.protocol.ProtocolHandler.class.isAssignableFrom(c))\n      throw new IllegalStateException(a[0] + \" does not implement ProtocolHandler\");\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  handler = ProtocolHandlerUtils.load(definition, narDir);\n} catch (IOException e) {\n  if (e.getMessage() != null && e.getMessage().contains(\"does not implement protocol handler interface\")) {\n    log.error(\"Declared handlerClass must implement ProtocolHandler\");\n  }\n  throw e;\n}","preventionTips":["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"],"tags":["broker","protocol-handler","classloader","nar"],"backgroundTag":"class-does-not-implement-interface","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}