{"record":{"id":"851b15ac45338d1d","repo":"apache/pulsar","slug":"no-additional-servlet-is-found-for-name-servlet","errorCode":null,"errorMessage":"No additional servlet is found for name `${servletName}`. Available additional servlet are : ${definitions}","messagePattern":"No additional servlet is found for name `(.+?)`\\. Available additional servlet are : (.+?)","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":95,"sourceCode":"\n        if (additionalServletDirectory == null || additionalServlets == null) {\n            return null;\n        }\n\n        String[] additionalServletsList = additionalServlets.split(\",\");\n        if (additionalServletsList.length == 0) {\n            return null;\n        }\n\n        AdditionalServletDefinitions definitions =\n                AdditionalServletUtils.searchForServlets(additionalServletDirectory\n                        , narExtractionDirectory);\n        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()) {","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/web/plugin/servlet/AdditionalServlets.java#L77-L113","documentation":"AdditionalServlets.load builds the servlet map from the configured additional servlet names; when a configured name has no matching entry in the discovered servlet definitions metadata (from the NAR packages), it throws this RuntimeException. It means a name in the broker's additionalServlets configuration does not correspond to any deployed servlet plugin.","triggerScenarios":"Broker config additionalServlets contains a servlet name that is not present in definitions.servlets() — i.e., no loaded NAR exposes a servlet with that exact name.","commonSituations":"Typo in the additionalServlets config value; the servlet NAR was never copied to the plugins directory; the NAR's metadata declares a different servlet name than the one configured; the NAR failed to be discovered (wrong directory or extraction failure).","solutions":["Compare the configured name against the names listed in the error message (Available additional servlet are: ...) and fix the typo","Verify the servlet NAR is present in the configured plugins directory and was extracted successfully","Check the servlet's metadata inside the NAR declares the name you used in configuration","Remove the stale name from additionalServlets if the plugin is no longer needed"],"exampleFix":"// before (broker.conf)\nadditionalServlets=my-servelt\n// after\nadditionalServlets=my-servlet","handlingStrategy":"validation","validationCode":"String requested = \"my-servlet\";\nif (!definitions.servlets().containsKey(requested)) {\n    throw new IllegalArgumentException(\"Servlet '\" + requested + \"' not deployed; available: \"\n        + definitions.servlets().keySet());\n}","typeGuard":null,"tryCatchPattern":"try {\n    servlets = AdditionalServlets.load(brokerConfig, narDir);\n} catch (RuntimeException e) {\n    if (e.getMessage().startsWith(\"No additional servlet is found\")) {\n        log.error(\"Configured additionalServlets name not found — check name and NAR deployment\", e);\n    }\n    throw e;\n}","preventionTips":["Copy servlet names exactly from the NAR's metadata","Confirm the NAR is in the plugins directory before referencing it in config","Remove names of plugins you have undeployed"],"tags":["servlet","plugin","configuration","broker"],"backgroundTag":"unknown-servlet-name","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"}