{"record":{"id":"0c208c8c47250a98","repo":"apache/pulsar","slug":"failed-to-load-message-payload-processor-class-sx","errorCode":null,"errorMessage":"Failed to load message payload processor class %sx","messagePattern":"Failed to load message payload processor class (.+?)x","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/MessagePayloadProcessorUtils.java","lineNumber":41,"sourceCode":"import com.google.gson.reflect.TypeToken;\nimport java.lang.reflect.Constructor;\nimport java.lang.reflect.InvocationTargetException;\nimport java.lang.reflect.Type;\nimport java.util.Map;\nimport org.apache.pulsar.client.api.MessagePayloadProcessor;\nimport org.apache.pulsar.common.functions.MessagePayloadProcessorConfig;\nimport org.apache.pulsar.common.util.ClassLoaderUtils;\nimport org.apache.pulsar.functions.proto.MessagePayloadProcessorSpec;\n\npublic class MessagePayloadProcessorUtils {\n    public static MessagePayloadProcessor getMessagePayloadProcessorInstance(String className,\n                                                                             Map<String, Object> configs,\n                                                                             ClassLoader classLoader) {\n        Class<?> payloadProcessorClass;\n        try {\n            payloadProcessorClass = ClassLoaderUtils.loadClass(className, classLoader);\n        } catch (ClassNotFoundException e) {\n            throw new RuntimeException(\n                    String.format(\"Failed to load message payload processor class %sx\", className));\n        }\n\n        try {\n            if (configs == null || configs.isEmpty()) {\n                Constructor<?> ctor = payloadProcessorClass.getConstructor();\n                return (MessagePayloadProcessor) ctor.newInstance();\n            } else {\n                Constructor<?> ctor = payloadProcessorClass.getConstructor(Map.class);\n                return (MessagePayloadProcessor) ctor.newInstance(configs);\n            }\n        } catch (NoSuchMethodException e) {\n            if (configs == null || configs.isEmpty()) {\n                throw new RuntimeException(\"Message payload processor class does not have default constructor\", e);\n            } else {\n                throw new RuntimeException(\"Message payload processor class does not have constructor accepts map\", e);\n            }\n        } catch (IllegalAccessException | InstantiationException | InvocationTargetException e) {","sourceCodeStart":23,"sourceCodeEnd":59,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/MessagePayloadProcessorUtils.java#L23-L59","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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"],"exampleFix":"// before\n\"className\": \"com.mycorp.processors.MyProcesor\"  // typo\n// after\n\"className\": \"com.mycorp.processors.MyProcessor\"","handlingStrategy":"validation","validationCode":"Class<?> c;\ntry {\n  c = Class.forName(spec.getClassName(), false, functionClassLoader);\n  if (!MessagePayloadProcessor.class.isAssignableFrom(c)) {\n    throw new IllegalStateException(spec.getClassName() + \" is not a MessagePayloadProcessor\");\n  }\n} catch (ClassNotFoundException e) {\n  throw new IllegalStateException(\"Payload processor class not packaged in function archive: \" + spec.getClassName());\n}","typeGuard":"boolean isValidPayloadProcessor(String name, ClassLoader cl) {\n  try {\n    return MessagePayloadProcessor.class.isAssignableFrom(Class.forName(name, false, cl));\n  } catch (ClassNotFoundException e) { return false; }\n}","tryCatchPattern":"try {\n  createFunction(...);\n} catch (RuntimeException e) {\n  if (e.getMessage() != null && e.getMessage().startsWith(\"Failed to load message payload processor class\")) {\n    log.error(\"Processor class not found: {}\", spec.getMessagePayloadProcessor().getClassName());\n  }\n}","preventionTips":["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"],"tags":["pulsar-functions","classnotfound","message-payload-processor","reflection"],"backgroundTag":"class-not-found","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}