apache/pulsar · warning · IOException

cause.getMessage()

Error message

cause.getMessage()

What it means

rethrowIOException normalizes a Throwable thrown while loading an additional servlet: IOException, RuntimeException, and Error are rethrown as-is; anything else is wrapped in a new IOException whose message is cause.getMessage(). Developers see this as an IOException during servlet (NAR) loading whose text is the underlying cause's message.

Solutions

  1. Inspect the IOException's message and its cause stack trace to find the underlying loading failure
  2. Rebuild/redeploy the servlet NAR — the cause is almost always in the plugin package
  3. Enable debug logging for the additional servlet loading path to capture the original throwable
Defensive patterns

Strategy: try-catch

Validate before calling

// Ensure the NAR file exists and is readable before load
java.io.File nar = new java.io.File(narPath);
if (!nar.isFile() || !nar.canRead()) throw new java.io.FileNotFoundException(narPath);

Try / catch

try {
    servlet = AdditionalServletUtils.load(definition, narDir);
} catch (IOException e) {
    // message is cause.getMessage(); inspect cause chain for the real failure
    Throwable root = e; while (root.getCause() != null) root = root.getCause();
    log.error("Servlet load failed, root cause: {}", root.toString(), e);
}

Prevention

When it happens

Trigger: AdditionalServletUtils.load encounters a checked, non-IOException, non-RuntimeException, non-Error Throwable during servlet class loading/instantiation (e.g. a custom checked exception from plugin static initializers or class definition failures surfaced as a checked type).

Common situations: Corrupt or incompatible NAR files whose classloading throws unusual checked exceptions; plugin code throwing custom checked exceptions during initialization; unusual filesystem errors surfaced through non-standard exception types.

Related errors


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

Appendix: source

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

                }
            }
            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)