{"record":{"id":"83b3d532a3036d28","repo":"apache/pulsar","slug":"class-handlerclass-does-not-implement-worker-se","errorCode":null,"errorMessage":"Class ${handlerClass} does not implement worker service interface","messagePattern":"Class (.+?) does not implement worker service interface","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"critical","filePath":"pulsar-functions/worker/src/main/java/org/apache/pulsar/functions/worker/service/WorkerServiceLoader.java","lineNumber":93,"sourceCode":"                                             String narExtractionDirectory) throws IOException {\n        final File narFile = metadata.getArchivePath().toAbsolutePath().normalize().toFile();\n        NarClassLoader ncl = NarClassLoaderBuilder.builder()\n                .narFile(narFile)\n                .parentClassLoader(WorkerService.class.getClassLoader())\n                .extractionDirectory(narExtractionDirectory)\n                .build();\n\n        WorkerServiceDefinition phDef = getWorkerServiceDefinition(ncl);\n        if (StringUtils.isBlank(phDef.getHandlerClass())) {\n            throw new IOException(\"Functions Worker Service Nar Package `\" + phDef.getName()\n                + \"` does NOT provide a functions worker service implementation\");\n        }\n\n        try {\n            Class<?> handlerClass = ncl.loadClass(phDef.getHandlerClass());\n            Object handler = handlerClass.getDeclaredConstructor().newInstance();\n            if (!(handler instanceof WorkerService)) {\n                throw new IOException(\"Class \" + phDef.getHandlerClass()\n                    + \" does not implement worker service interface\");\n            }\n            WorkerService ph = (WorkerService) handler;\n            return new WorkerServiceWithClassLoader(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":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-functions/worker/src/main/java/org/apache/pulsar/functions/worker/service/WorkerServiceLoader.java#L75-L111","documentation":"WorkerServiceLoader.load() instantiates the handler class declared in the NAR's WorkerServiceDefinition. If the instantiated object does not implement the org.apache.pulsar.functions.worker.service.WorkerService interface, loading fails with this IOException. The NAR metadata exists but points at a class with the wrong type.","triggerScenarios":"A NAR whose WorkerServiceDefinition.handlerClass names a class that exists and instantiates but is not a WorkerService (custom fork drift, wrong class name in metadata, or a re-implemented handler after an interface rename).","commonSituations":"Building a custom worker NAR against an incompatible Pulsar API version where WorkerService changed; typos or copy-paste errors in the handlerClass metadata entry; refactoring a handler class without updating its implemented interface.","solutions":["Make the declared handler class implement org.apache.pulsar.functions.worker.service.WorkerService","Fix the handlerClass entry in the NAR's WorkerServiceDefinition to point at the correct class","Rebuild the NAR against the same Pulsar version as the broker so the WorkerService interface matches"],"exampleFix":"// before\npublic class MyWorker { /* no WorkerService */ }\n// after\npublic class MyWorker implements WorkerService {\n    @Override public void initialize(WorkerConfig config, AuthenticationProtocol auth) { ... }\n    @Override public void start() { ... }\n}","handlingStrategy":"validation","validationCode":"// confirm the handler class in the NAR implements WorkerService before deployment\nclasspath-load handlerClass;\nif (!WorkerService.class.isInstance(instantiated)) throw new IllegalStateException(\"handlerClass is not a WorkerService\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Ensure custom NAR handler classes implement WorkerService","Rebuild custom worker NARs against the same Pulsar version as the broker","Validate handlerClass entries in WorkerServiceDefinition metadata in CI","Smoke-test the NAR with a standalone worker before production rollout"],"tags":["nar-package","startup","class-loading"],"backgroundTag":"invalid-nar-package","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"}