apache/pulsar · error · IllegalArgumentException
Cannot find/load class
Error message
Cannot find/load class ${className} What it means
Thrown by the multi-class validator when Class.forName-style loading of the configured class name throws ClassNotFoundException. The class name string in the config field could not be resolved by the thread context classloader, so no assignment check is even possible.
Solutions
- Correct the fully-qualified class name in the config (spelling, package, casing).
- Add the jar/module containing the class to the deployment classpath (e.g. Pulsar Functions' extra deps /nar or lib directory).
- Confirm with the same classloader that will load at runtime — Thread.currentThread().getContextClassLoader() — that Class.forName(name, true, loader) succeeds.
- Check for renames between library versions and update config accordingly.
Example fix
// before (config) authPlugin = org.apache.pulsar.client.impl.auth.AutinizationToken // typo // after authPlugin = org.apache.pulsar.client.impl.auth.AuthenticationToken
Defensive patterns
Strategy: validation
Validate before calling
static boolean classLoadable(String className) {
try {
Class.forName(className, false, Thread.currentThread().getContextClassLoader());
return true;
} catch (ClassNotFoundException e) {
return false;
}
}
// call before applying config: classLoadable(cfgValue) Try / catch
try {
validator.validateField("authPlugin", pluginClassName);
} catch (IllegalArgumentException e) {
log.error("Cannot load configured class {} — check class name and classpath", pluginClassName, e);
throw new ConfigurationException(e.getMessage(), e);
} Prevention
- Copy fully-qualified class names from the library's javadoc, not from memory.
- Verify dependency jars are shipped with the deployment (lib/, nar, extra-deps).
- After upgrades, grep release notes for renamed/moved classes referenced in config.
- Test class loading in the target runtime environment, not just the build environment.
When it happens
Trigger: A config field validated against several required interfaces calls loadClass(className); if the class is absent from the classpath (wrong name, missing jar, wrong package), the ClassNotFoundException is wrapped into this IllegalArgumentException.
Common situations: Typo in fully-qualified class name; dependency jar not shipped with the deployment; class exists only in test scope; class moved/renamed after an upgrade; config copied between environments with different classpaths.
Related errors
- Field ' ' with value ' ' does not implement
- Could not find source config class
- Field is not an accepted value. Value: Accepted values
- Field must be of type . Object: actual type
- Field ' ' with value ' ' does not implement any of these…
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/fe61745276e9aeb5.
Report an issue: GitHub.
Appendix: source
Thrown at pulsar-config-validation/src/main/java/org/apache/pulsar/config/validation/ValidatorImpls.java:193
public ImplementsClassesValidator(Map<String, Object> params) {
this.classesImplements = (Class<?>[]) params.get(
ConfigValidationAnnotations.ValidatorParams.IMPLEMENTS_CLASSES);
}
@Override
public void validateField(String name, Object o) {
if (o == null) {
return;
}
SimpleTypeValidator.validateField(name, String.class, o);
String className = (String) o;
int count = 0;
for (Class<?> classImplements : classesImplements) {
Class<?> objectClass = null;
try {
objectClass = loadClass(className);
} catch (ClassNotFoundException e) {
throw new IllegalArgumentException("Cannot find/load class " + className);
}
if (classImplements.isAssignableFrom(objectClass)) {
count++;
}
}
if (count == 0) {
throw new IllegalArgumentException(
String.format("Field '%s' with value '%s' does not implement any of these classes %s",
name, o, Arrays.toString(classesImplements)));
}
}
}
/**
* validates each key and each value against the respective arrays of validators.
*/
public static class MapEntryCustomValidator extends Validator {View on GitHub (pinned to 820761864e)