apache/pulsar · error · RuntimeException
Config class not found: %s
Error message
Config class not found: %s
What it means
The function declares a typed config (configClassName in FunctionDetails) but Class.forName cannot load that class from the component classloader during instance construction. The runtime needs the config class to reflect over its bean properties and inject user configuration, so it fails hard wrapping the ClassNotFoundException.
Source
Thrown at pulsar-functions/instance/src/main/java/org/apache/pulsar/functions/instance/JavaInstanceRunnable.java:1043
interpolateSecretsIntoConfigs(secretsProvider, config);
if (instanceConfig.isIgnoreUnknownConfigFields() && componentClassLoader instanceof NarClassLoader) {
final String configClassName;
if (componentType == FunctionDetails.ComponentType.SOURCE) {
configClassName = ConnectorUtils
.getConnectorDefinition((NarClassLoader) componentClassLoader).getSourceConfigClass();
} else {
configClassName = ConnectorUtils
.getConnectorDefinition((NarClassLoader) componentClassLoader).getSinkConfigClass();
}
if (configClassName != null) {
Class<?> configClass;
try {
configClass = Class.forName(configClassName,
true, Thread.currentThread().getContextClassLoader());
} catch (ClassNotFoundException e) {
throw new RuntimeException("Config class not found: " + configClassName, e);
}
final List<String> allFields = BeanPropertiesReader.getBeanProperties(configClass);
for (String s : config.keySet()) {
if (!allFields.contains(s)) {
log.error()
.attr("field", s)
.attr("componentType", componentType)
.attr("configClass", configClass)
.log("Field not defined in the configuration,"
+ " the field will be ignored");
config.remove(s);
}
}
}
}
return config;
}View on GitHub (pinned to 820761864e)
Solutions
- Verify the exact fully-qualified class name in the function config matches a class present in the uploaded JAR (unzip -l function.jar)
- If using maven-shade, ensure the config class package is not relocated, or update the config className accordingly
- Rebuild and redeploy the JAR containing the config class before submitting/updating the function
- For nested classes use the binary name with $ (com.example.Foo$Config)
Example fix
// before (function config)
{"className":"com.acme.MySource","configClassName":"com.acme.MyOldSourceConfig"}
// after
{"className":"com.acme.MySource","configClassName":"com.acme.MySourceConfig"} Defensive patterns
Strategy: validation
Validate before calling
String cn = details.getConfigClassName(); Class.forName(cn, true, functionClassLoader); // fails fast before submission
Try / catch
try { submitFunction(cfg); }
catch (RuntimeException e) {
if (e.getMessage().startsWith("Config class not found")) {
log.error("Verify configClassName exists in the uploaded JAR", e);
}
} Prevention
- Keep configClassName in sync when renaming/refactoring packages
- Check JAR contents (unzip -l) for the config class before uploading
- Avoid shade-plugin relocations of config classes
- Use binary names with $ for nested config classes
When it happens
Trigger: The className string in the function config doesn't match the fully-qualified name of a class in the function JAR; the JAR containing the config class wasn't uploaded; the class is in the uber JAR but shaded/moved by a relocation rule; typo in package name.
Common situations: Renaming the config class package without redeploying the JAR; building the function with shading that relocates the config class; specifying an inner class name with wrong separator (Foo.Bar vs Foo$Bar); deploying a source/sink JAR that omits the config class.
Related errors
- Unable to initialize crypto config %s
- The input serialization/deserialization class %s does not ex
- Failed to load an authorization provider.
- No java.security.Provider named '${name}' could be resolved
- Component cannot get state store
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/834c05b1488b24e4.
Report an issue: GitHub.