apache/pulsar · critical · RuntimeException

Failed to load the protocol handler for protocol `${protocol

Error message

Failed to load the protocol handler for protocol `${protocol}`

What it means

Thrown by ProtocolHandlers.load when ProtocolHandlerUtils.load throws an IOException (definition missing handler class, class not found, instantiation failure, etc.). The broker wraps the cause in a RuntimeException naming the protocol.

Source

Thrown at pulsar-broker/src/main/java/org/apache/pulsar/broker/protocol/ProtocolHandlers.java:80

        ImmutableMap.Builder<String, ProtocolHandlerWithClassLoader> handlersBuilder = ImmutableMap.builder();

        conf.getMessagingProtocols().forEach(protocol -> {

            ProtocolHandlerMetadata definition = definitions.handlers().get(protocol);
            if (null == definition) {
                throw new RuntimeException("No protocol handler is found for protocol `" + protocol
                    + "`. Available protocols are : " + definitions.handlers());
            }

            ProtocolHandlerWithClassLoader handler;
            try {
                handler = ProtocolHandlerUtils.load(definition, conf.getNarExtractionDirectory());
            } catch (IOException e) {
                log.error()
                        .attr("protocol", protocol)
                        .exception(e)
                        .log("Failed to load the protocol handler for protocol ` `");
                throw new RuntimeException("Failed to load the protocol handler for protocol `" + protocol + "`");
            }

            if (!handler.accept(protocol)) {
                handler.close();
                log.error().attr("protocol", protocol).log("Malformed protocol handler found for protocol ` `");
                throw new RuntimeException("Malformed protocol handler found for protocol `" + protocol + "`");
            }

            handlersBuilder.put(protocol, handler);
            log.info().attr("protocol", protocol).log("Successfully loaded protocol handler for protocol ``");
        });

        return new ProtocolHandlers(handlersBuilder.build());
    }

    private final Map<String, ProtocolHandlerWithClassLoader> handlers;

    ProtocolHandlers(Map<String, ProtocolHandlerWithClassLoader> handlers) {

View on GitHub (pinned to 820761864e)

Solutions

  1. Read the nested IOException cause in the log to identify the root failure (missing class, version mismatch, corrupt NAR).
  2. Rebuild the NAR against the broker's Pulsar version and redeploy it to protocols/.
  3. Confirm narExtractionDirectory is writable and has disk space so the NAR can be unpacked.
  4. Run the broker with the JDK version required by the handler NAR.
Defensive patterns

Strategy: try-catch

Validate before calling

// Check the NAR is a valid zip and sized correctly before deployment
java.util.zip.ZipFile z = null;
try { z = new java.util.zip.ZipFile(narPath); }
catch (java.io.IOException e) { throw new IllegalStateException("Corrupt NAR: " + narPath, e); }
finally { if (z != null) z.close(); }

Try / catch

try {
  handlers = ProtocolHandlers.load(conf);
} catch (RuntimeException e) {
  if (e.getMessage() != null && e.getMessage().startsWith("Failed to load the protocol handler")) {
    Throwable root = e;
    while (root.getCause() != null) root = root.getCause();
    log.error("Handler load failed; root cause: " + root); // NoClassDefFound/NoSuchMethod => version skew
  }
  throw e;
}

Prevention

When it happens

Trigger: Any failure in ProtocolHandlerUtils.load for a configured protocol: unreadable NAR, missing handlerClass (error 270), class load/instantiation errors, incompatible API during initialize.

Common situations: NAR compiled against a different Pulsar version causing NoSuchMethodError during load; corrupt NAR file in protocols/; JDK version mismatch; extraction directory not writable.

Related errors


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