apache/pulsar · error · RuntimeException

No additional servlet is found for name `${servletName}`. Av

Error message

No additional servlet is found for name `${servletName}`. Available additional servlet are : ${definitions}

What it means

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.

Source

Thrown at pulsar-broker-common/src/main/java/org/apache/pulsar/broker/web/plugin/servlet/AdditionalServlets.java:95

        if (additionalServletDirectory == null || additionalServlets == null) {
            return null;
        }

        String[] additionalServletsList = additionalServlets.split(",");
        if (additionalServletsList.length == 0) {
            return null;
        }

        AdditionalServletDefinitions definitions =
                AdditionalServletUtils.searchForServlets(additionalServletDirectory
                        , narExtractionDirectory);
        ImmutableMap.Builder<String, AdditionalServletWithClassLoader> builder = ImmutableMap.builder();

        for (String servletName : additionalServletsList) {
            AdditionalServletMetadata definition = definitions.servlets().get(servletName);
            if (null == definition) {
                throw new RuntimeException("No additional servlet is found for name `" + servletName
                        + "`. Available additional servlet are : " + definitions.servlets());
            }

            AdditionalServletWithClassLoader servletWithClassLoader;
            try {
                servletWithClassLoader = AdditionalServletUtils.load(definition, narExtractionDirectory);
                if (servletWithClassLoader != null) {
                    builder.put(servletName, servletWithClassLoader);
                }
                log.info().attr("servlet", servletName).log("Successfully loaded additional servlet");
            } catch (IOException e) {
                log.error().attr("servlet", servletName).exception(e).log("Failed to load the additional servlet");
                throw new RuntimeException("Failed to load the additional servlet for name `" + servletName + "`");
            }
        }

        Map<String, AdditionalServletWithClassLoader> servlets = builder.build();
        if (!servlets.isEmpty()) {

View on GitHub (pinned to 820761864e)

Solutions

  1. Compare the configured name against the names listed in the error message (Available additional servlet are: ...) and fix the typo
  2. Verify the servlet NAR is present in the configured plugins directory and was extracted successfully
  3. Check the servlet's metadata inside the NAR declares the name you used in configuration
  4. Remove the stale name from additionalServlets if the plugin is no longer needed

Example fix

// before (broker.conf)
additionalServlets=my-servelt
// after
additionalServlets=my-servlet
Defensive patterns

Strategy: validation

Validate before calling

String requested = "my-servlet";
if (!definitions.servlets().containsKey(requested)) {
    throw new IllegalArgumentException("Servlet '" + requested + "' not deployed; available: "
        + definitions.servlets().keySet());
}

Try / catch

try {
    servlets = AdditionalServlets.load(brokerConfig, narDir);
} catch (RuntimeException e) {
    if (e.getMessage().startsWith("No additional servlet is found")) {
        log.error("Configured additionalServlets name not found — check name and NAR deployment", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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).

Related errors


AI-assisted analysis of apache/pulsar@820761864e (2026-09-06). Data as JSON: /api/errors/851b15ac45338d1d. Report an issue: GitHub.