{"record":{"id":"6218b2adb119fced","repo":"apache/pulsar","slug":"failed-to-load-the-additional-servlet-for-name","errorCode":null,"errorMessage":"Failed to load the additional servlet for name `${servletName}`","messagePattern":"Failed to load the additional servlet for name `(.+?)`","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"pulsar-broker-common/src/main/java/org/apache/pulsar/broker/web/plugin/servlet/AdditionalServlets.java","lineNumber":108,"sourceCode":"        ImmutableMap.Builder<String, AdditionalServletWithClassLoader> builder = ImmutableMap.builder();\n\n        for (String servletName : additionalServletsList) {\n            AdditionalServletMetadata definition = definitions.servlets().get(servletName);\n            if (null == definition) {\n                throw new RuntimeException(\"No additional servlet is found for name `\" + servletName\n                        + \"`. Available additional servlet are : \" + definitions.servlets());\n            }\n\n            AdditionalServletWithClassLoader servletWithClassLoader;\n            try {\n                servletWithClassLoader = AdditionalServletUtils.load(definition, narExtractionDirectory);\n                if (servletWithClassLoader != null) {\n                    builder.put(servletName, servletWithClassLoader);\n                }\n                log.info().attr(\"servlet\", servletName).log(\"Successfully loaded additional servlet\");\n            } catch (IOException e) {\n                log.error().attr(\"servlet\", servletName).exception(e).log(\"Failed to load the additional servlet\");\n                throw new RuntimeException(\"Failed to load the additional servlet for name `\" + servletName + \"`\");\n            }\n        }\n\n        Map<String, AdditionalServletWithClassLoader> servlets = builder.build();\n        if (!servlets.isEmpty()) {\n            return new AdditionalServlets(servlets);\n        }\n\n        return null;\n    }\n\n    @Override\n    public void close() {\n        servlets.values().forEach(AdditionalServletWithClassLoader::close);\n    }\n}\n","sourceCodeStart":90,"sourceCodeEnd":125,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/web/plugin/servlet/AdditionalServlets.java#L90-L125","documentation":"When AdditionalServletUtils.load throws an IOException while loading a configured servlet (NAR extraction, classloading, instantiation), this RuntimeException is thrown with the servlet name in the message. The original IOException is logged at error level before rethrow, so the root cause is in the log, not in the exception message.","triggerScenarios":"IOException propagated from AdditionalServletUtils.load during the servlet NAR load — failed NAR file read, extraction directory problems, or class instantiation failures wrapped as IOException (see rethrowIOException).","commonSituations":"Corrupted or incomplete NAR upload; no read permission on the NAR file or no write permission on the NAR extraction directory; disk full during extraction; plugin class throws during initialization.","solutions":["Look at the preceding 'Failed to load the additional servlet' error log entry for the full IOException stack trace","Verify the NAR file is a valid, uncorrupted zip with correct permissions","Check the narExtractionDirectory exists, is writable, and has free disk space","Rebuild the plugin NAR if its classes fail to initialize on your Pulsar version"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// pre-check the NAR and extraction dir\nif (!Files.isReadable(Path.of(narPath)) || !Files.isWritable(Path.of(narExtractionDirectory))) {\n    throw new IllegalStateException(\"NAR unreadable or extraction directory not writable\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    servlets = AdditionalServlets.load(brokerConfig, narDir);\n} catch (RuntimeException e) {\n    // root IOException was logged by the library; surface it with context\n    throw new IllegalStateException(\"Additional servlet failed to load; see prior error log for the IOException\", e);\n}","preventionTips":["Check disk space and permissions on the NAR extraction directory","Validate NAR files after transfer (checksums)","Match plugin versions to the broker version"],"tags":["servlet","plugin","io","nar"],"backgroundTag":"servlet-load-failure","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}