apache/pulsar · error · IllegalArgumentException
The message payload processor class %s does not exist
Error message
The message payload processor class %s does not exist
What it means
validateMessagePayloadProcessor resolves conf.getClassName() via a ByteBuddy TypePool; when the named MessagePayloadProcessor class cannot be found on the classpath (NoSuchTypeException) this IllegalArgumentException is thrown. The payload processor handles BatchSource payload decoding (e.g. Avro, Parquet).
Source
Thrown at pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/ValidatorUtils.java:113
conf.getCryptoKeyReaderClassName()));
}
if (isProducer && (conf.getEncryptionKeys() == null || conf.getEncryptionKeys().length == 0)) {
throw new IllegalArgumentException("Missing encryption key name for producer crypto key reader");
}
}
public static void validateMessagePayloadProcessor(MessagePayloadProcessorConfig conf, TypePool typePool) {
if (isEmpty(conf.getClassName())) {
return;
}
String payloadProcessorClassName = conf.getClassName();
TypeDescription payloadProcessorClass = null;
try {
payloadProcessorClass = typePool.describe(payloadProcessorClassName).resolve();
} catch (TypePool.Resolution.NoSuchTypeException e) {
throw new IllegalArgumentException(
String.format("The message payload processor class %s does not exist", payloadProcessorClassName));
}
if (!payloadProcessorClass.asErasure().isAssignableTo(MessagePayloadProcessor.class)) {
throw new IllegalArgumentException(String.format("%s does not implement %s", payloadProcessorClassName,
MessagePayloadProcessor.class.getName()));
}
boolean hasConstructor;
if (conf.getConfig() == null || conf.getConfig().isEmpty()) {
hasConstructor = payloadProcessorClass.getDeclaredMethods().stream()
.anyMatch(method -> method.isConstructor() && method.getParameters().size() == 0);
} else {
hasConstructor = payloadProcessorClass.getDeclaredMethods().stream()
.anyMatch(method -> method.isConstructor() && method.getParameters().size() == 1
&& method.getParameters().get(0).getType().asErasure().represents(Map.class));
}
if (!hasConstructor) {View on GitHub (pinned to 820761864e)
Solutions
- Correct the className in the payload processor config
- Package the MessagePayloadProcessor implementation into the submitted jar
- Use a processor class confirmed to exist in your Pulsar version (check the org.apache.pulsar.functions.utils.collections / processor packages for your release)
Example fix
// before // className: com.acme.OldProcessor // removed in this Pulsar version // after // className: org.apache.pulsar.functions.avro.AvroPayloadProcessor // exists in classpath
Defensive patterns
Strategy: validation
Validate before calling
try {
Class.forName(conf.getClassName());
} catch (ClassNotFoundException e) {
throw new IllegalStateException("Payload processor class missing: " + conf.getClassName());
} Try / catch
try {
ValidatorUtils.validateMessagePayloadProcessor(conf, typePool);
} catch (IllegalArgumentException e) {
if (e.getMessage().endsWith("does not exist")) {
// correct className or package the processor class
}
throw e;
} Prevention
- Confirm the processor class exists in your Pulsar release before referencing it
- Package custom processors in the function jar
- Watch for package renames across Pulsar upgrades and update configs accordingly
When it happens
Trigger: Configuring a MessagePayloadProcessorConfig with a className that is missing from the function jar or worker classpath, or a typo in the FQCN.
Common situations: Referencing a built-in processor class (e.g. AvroPayloadProcessor) that is not shipped with the worker version; custom processor jar not uploaded; package renamed across Pulsar releases.
Related errors
- The schema class %s does not exist
- The crypto key reader class %s does not exist
- Config class not found: %s
- Unable to initialize crypto config %s
- Could not find source config class
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/56d3623353822ff1.
Report an issue: GitHub.