apache/pulsar · error · IllegalArgumentException

Unsupported additional servlet type ${servletType}

Error message

Unsupported additional servlet type ${servletType}

What it means

toJakartaServlet adapts an additional servlet's instance to jakarta.servlet.Servlet based on the servlet type the plugin declares. A switch over AdditionalServletType only knows JAVAX_SERVLET and JAKARTA_SERVLET; any other enum value reaches the default branch and throws this IllegalArgumentException. Today this mainly guards against null/unexpected values from a misimplemented or foreign plugin.

Source

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

     * @return the servlet instance as a {@code jakarta.servlet.Servlet}
     * @throws IllegalArgumentException if the servlet instance doesn't implement the servlet interface required
     *         by the {@link AdditionalServlet#getServletType() servlet type} the additional servlet declares
     */
    public Servlet toJakartaServlet(AdditionalServlet additionalServlet) {
        AdditionalServletType servletType = additionalServlet.getServletType();
        Object servletInstance = additionalServlet.getServletInstance();
        switch (servletType) {
            case JAVAX_SERVLET -> {
                if (servletInstance instanceof javax.servlet.Servlet javaxServlet) {
                    return new ServletWrapper(javaxServlet);
                }
            }
            case JAKARTA_SERVLET -> {
                if (servletInstance instanceof Servlet jakartaServlet) {
                    return jakartaServlet;
                }
            }
            default -> throw new IllegalArgumentException("Unsupported additional servlet type " + servletType);
        }
        throw new IllegalArgumentException("Additional servlet instance of type "
                + (servletInstance == null ? "null" : servletInstance.getClass().getName())
                + " doesn't implement the servlet interface required by the declared servlet type " + servletType);
    }

    private void rethrowIOException(Throwable cause)
            throws IOException {
        if (cause instanceof IOException) {
            throw (IOException) cause;
        } else if (cause instanceof RuntimeException) {
            throw (RuntimeException) cause;
        } else if (cause instanceof Error) {
            throw (Error) cause;
        } else {
            throw new IOException(cause.getMessage(), cause);
        }
    }

View on GitHub (pinned to 820761864e)

Solutions

  1. Set the servlet type to JAVAX_SERVLET or JAKARTA_SERVLET in the plugin's getServletType() implementation and rebuild the NAR
  2. Upgrade or fix the plugin so it declares one of the two supported AdditionalServletType values matching your Pulsar version
  3. Ensure the servlet instance actually implements the interface matching the declared type (javax.servlet.Servlet vs jakarta.servlet.Servlet) to avoid the adjacent mismatch error

Example fix

// before
@Override public AdditionalServletType getServletType() { return null; }
// after
@Override public AdditionalServletType getServletType() { return AdditionalServletType.JAKARTA_SERVLET; }
Defensive patterns

Strategy: type-guard

Validate before calling

AdditionalServletType t = plugin.getServletType();
if (t != AdditionalServletType.JAVAX_SERVLET && t != AdditionalServletType.JAKARTA_SERVLET)
    throw new IllegalStateException("unsupported servlet type: " + t);

Type guard

boolean hasSupportedServletType(AdditionalServlet p) {
    return p.getServletType() == AdditionalServletType.JAVAX_SERVLET
        || p.getServletType() == AdditionalServletType.JAKARTA_SERVLET;
}

Try / catch

try {
    Servlet s = AdditionalServletUtils.toJakartaServlet(plugin);
} catch (IllegalArgumentException e) {
    log.error("Cannot adapt servlet plugin: {}", e.getMessage());
}

Prevention

When it happens

Trigger: A custom AdditionalServlet's getServletType() returns null (default branch hit via switch on null enum throws NPE) or a non-standard AdditionalServletType value added by a custom build; calling toJakartaServlet on a plugin whose enum constant is not one of the two supported types.

Common situations: Plugin written against a newer/older Pulsar API with an extra servlet type; a plugin incorrectly returning null from getServletType(); testing a hand-rolled AdditionalServlet implementation without setting servletType.

Related errors


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