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
- Inspect the wrapped cause (getCause()) — for InvocationTargetException the real error is its cause
- Make the processor class concrete and its Map/no-arg constructor public
- Validate config values inside the constructor or fail fast with a descriptive message before throwing
- 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
- Never throw from processor constructors on partially-valid config — validate lazily
- Keep the class concrete (non-abstract) and constructors public
- Always unwind getCause() chains: InvocationTargetException hides the real error
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
- Failed to load message payload processor class %sx
- Message payload processor class does not have default constr
- Message payload processor class does not have constructor ac
- Failed to instantiate ${className}
- Could not instantiate <configKeyName> '<factoryClassName>'
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/27cc7a4a0bfdb41a.
Report an issue: GitHub.