apache/pulsar · error · RuntimeException
Failed to load message payload processor class %sx
Error message
Failed to load message payload processor class %sx
What it means
getMessagePayloadProcessorInstance loads the configured MessagePayloadProcessor class via ClassLoaderUtils.loadClass; on ClassNotFoundException it throws a RuntimeException with this message (note the stray 'x' typo in the format string, e.g. 'com.foo.MyProcessorx'). The 'x' is a formatting artifact, not part of the class name.
Source
Thrown at pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/MessagePayloadProcessorUtils.java:41
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Type;
import java.util.Map;
import org.apache.pulsar.client.api.MessagePayloadProcessor;
import org.apache.pulsar.common.functions.MessagePayloadProcessorConfig;
import org.apache.pulsar.common.util.ClassLoaderUtils;
import org.apache.pulsar.functions.proto.MessagePayloadProcessorSpec;
public class MessagePayloadProcessorUtils {
public static MessagePayloadProcessor getMessagePayloadProcessorInstance(String className,
Map<String, Object> configs,
ClassLoader classLoader) {
Class<?> payloadProcessorClass;
try {
payloadProcessorClass = ClassLoaderUtils.loadClass(className, classLoader);
} catch (ClassNotFoundException e) {
throw new RuntimeException(
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) {View on GitHub (pinned to 820761864e)
Solutions
- Correct the className in the function configuration (the 'x' suffix is a bug — the real name is what precedes it)
- Package the payload processor class into the function archive
- Verify the class exists: 'unzip -l function.jar | grep MessagePayloadProcessor'
- Confirm you are loading through the right class loader (function jar vs worker) and that no NAR isolation hides the class
Example fix
// before "className": "com.mycorp.processors.MyProcesor" // typo // after "className": "com.mycorp.processors.MyProcessor"
Defensive patterns
Strategy: validation
Validate before calling
Class<?> c;
try {
c = Class.forName(spec.getClassName(), false, functionClassLoader);
if (!MessagePayloadProcessor.class.isAssignableFrom(c)) {
throw new IllegalStateException(spec.getClassName() + " is not a MessagePayloadProcessor");
}
} catch (ClassNotFoundException e) {
throw new IllegalStateException("Payload processor class not packaged in function archive: " + spec.getClassName());
} Type guard
boolean isValidPayloadProcessor(String name, ClassLoader cl) {
try {
return MessagePayloadProcessor.class.isAssignableFrom(Class.forName(name, false, cl));
} catch (ClassNotFoundException e) { return false; }
} Try / catch
try {
createFunction(...);
} catch (RuntimeException e) {
if (e.getMessage() != null && e.getMessage().startsWith("Failed to load message payload processor class")) {
log.error("Processor class not found: {}", spec.getMessagePayloadProcessor().getClassName());
}
} Prevention
- Package the processor class in the function archive itself
- Copy-paste fully qualified names instead of typing them (ignore the trailing 'x' — it is a message-format bug in the library)
- Validate the class exists in the function JAR before deploying
When it happens
Trigger: Creating/running a function whose messagePayloadProcessor spec contains a className that cannot be resolved through the supplied class loader (function package classloader or worker classloader).
Common situations: Typo in className; processor class not packaged in the function's JAR/NAR; processor built against a different package than deployed; class only present in a NAR while the loader is the jar loader.
Related errors
- Message payload processor class does not have default constr
- Message payload processor class does not have constructor ac
- Failed to create instance for message payload processor clas
- functions may not take more than two arguments, but function
- function takes two arguments, but the first is not Context.
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/0c208c8c47250a98.
Report an issue: GitHub.