apache/pulsar · error · RuntimeException

Failed to create instance for message payload processor clas

Error message

Failed to create instance for message payload processor class

What it means

If the constructor is found but newInstance fails — the constructor is inaccessible (IllegalAccessException), the class is abstract/interface (InstantiationException), or the constructor itself throws (InvocationTargetException) — this generic RuntimeException is thrown wrapping the reflective cause.

Source

Thrown at pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/MessagePayloadProcessorUtils.java:60

                    String.format("Failed to load message payload processor class %sx", className));
        }

        try {
            if (configs == null || configs.isEmpty()) {
                Constructor<?> ctor = payloadProcessorClass.getConstructor();
                return (MessagePayloadProcessor) ctor.newInstance();
            } else {
                Constructor<?> ctor = payloadProcessorClass.getConstructor(Map.class);
                return (MessagePayloadProcessor) ctor.newInstance(configs);
            }
        } catch (NoSuchMethodException e) {
            if (configs == null || configs.isEmpty()) {
                throw new RuntimeException("Message payload processor class does not have default constructor", e);
            } else {
                throw new RuntimeException("Message payload processor class does not have constructor accepts map", e);
            }
        } catch (IllegalAccessException | InstantiationException | InvocationTargetException e) {
            throw new RuntimeException("Failed to create instance for message payload processor class", e);
        }
    }

    public static MessagePayloadProcessorConfig convertFromSpec(MessagePayloadProcessorSpec spec) {
        if (spec == null || isEmpty(spec.getClassName())) {
            return null;
        }

        MessagePayloadProcessorConfig.MessagePayloadProcessorConfigBuilder bldr =
                MessagePayloadProcessorConfig.builder();

        Type type = new TypeToken<Map<String, Object>>() {
        }.getType();
        Map<String, Object> configs = new Gson().fromJson(spec.getConfigs(), type);

        bldr.className(spec.getClassName()).config(configs);

        return bldr.build();

View on GitHub (pinned to 820761864e)

Solutions

  1. Inspect the wrapped cause (getCause()) — for InvocationTargetException the real error is its cause
  2. Make the processor class concrete and its Map/no-arg constructor public
  3. Validate config values inside the constructor or fail fast with a descriptive message before throwing
  4. Initialize external dependencies (clients, clients caches) lazily or defensively in the constructor

Example fix

// before
MyProcessor(Map<String,Object> cfg) {
  this.poolSize = (Integer) cfg.get("poolSize"); // NPE when key missing
}
// after
MyProcessor(Map<String,Object> cfg) {
  this.poolSize = Integer.parseInt(String.valueOf(cfg.getOrDefault("poolSize", "4")));
}
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-check: class is concrete and has an accessible constructor
Class<?> c = Class.forName(className, false, cl);
if (Modifier.isAbstract(c.getModifiers())) throw new IllegalStateException(className + " is abstract");
c.getConstructor(); // or getConstructor(Map.class) per config mode

Try / catch

try {
  createFunction(...);
} catch (RuntimeException e) {
  if ("Failed to create instance for message payload processor class".equals(e.getMessage())) {
    // InvocationTargetException wraps the constructor's own exception
    Throwable root = e;
    while (root.getCause() != null) root = root.getCause();
    log.error("Processor constructor threw: {}", root.getMessage(), root);
  }
}

Prevention

When it happens

Trigger: The payload processor class has the expected constructor, but instantiation fails: class is abstract, constructor is not public, or the constructor body threw an exception (bad config cast, dependency initialization failure).

Common situations: Constructor throws NPE/ClassCastException on config values; class declared abstract or only implemented by an interface; constructor not public (package-private after refactor); InvocationTargetException cause chain hiding the real error.

Related errors


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