{"record":{"id":"fe61745276e9aeb5","repo":"apache/pulsar","slug":"cannot-find-load-class-classname","errorCode":null,"errorMessage":"Cannot find/load class ${className}","messagePattern":"Cannot find/load class (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"pulsar-config-validation/src/main/java/org/apache/pulsar/config/validation/ValidatorImpls.java","lineNumber":193,"sourceCode":"        public ImplementsClassesValidator(Map<String, Object> params) {\n            this.classesImplements = (Class<?>[]) params.get(\n                    ConfigValidationAnnotations.ValidatorParams.IMPLEMENTS_CLASSES);\n        }\n\n        @Override\n        public void validateField(String name, Object o) {\n            if (o == null) {\n                return;\n            }\n            SimpleTypeValidator.validateField(name, String.class, o);\n            String className = (String) o;\n            int count = 0;\n            for (Class<?> classImplements : classesImplements) {\n                Class<?> objectClass = null;\n                try {\n                    objectClass = loadClass(className);\n                } catch (ClassNotFoundException e) {\n                    throw new IllegalArgumentException(\"Cannot find/load class \" + className);\n                }\n\n                if (classImplements.isAssignableFrom(objectClass)) {\n                    count++;\n                }\n            }\n            if (count == 0) {\n                throw new IllegalArgumentException(\n                        String.format(\"Field '%s' with value '%s' does not implement any of these classes %s\",\n                                name, o, Arrays.toString(classesImplements)));\n            }\n        }\n    }\n\n    /**\n     * validates each key and each value against the respective arrays of validators.\n     */\n    public static class MapEntryCustomValidator extends Validator {","sourceCodeStart":175,"sourceCodeEnd":211,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-config-validation/src/main/java/org/apache/pulsar/config/validation/ValidatorImpls.java#L175-L211","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before (config)\nauthPlugin = org.apache.pulsar.client.impl.auth.AutinizationToken  // typo\n// after\nauthPlugin = org.apache.pulsar.client.impl.auth.AuthenticationToken","handlingStrategy":"validation","validationCode":"static boolean classLoadable(String className) {\n    try {\n        Class.forName(className, false, Thread.currentThread().getContextClassLoader());\n        return true;\n    } catch (ClassNotFoundException e) {\n        return false;\n    }\n}\n// call before applying config: classLoadable(cfgValue)","typeGuard":null,"tryCatchPattern":"try {\n    validator.validateField(\"authPlugin\", pluginClassName);\n} catch (IllegalArgumentException e) {\n    log.error(\"Cannot load configured class {} — check class name and classpath\", pluginClassName, e);\n    throw new ConfigurationException(e.getMessage(), e);\n}","preventionTips":["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."],"tags":["java","classnotfound","config-validation","classloader"],"backgroundTag":"classnotfoundexception","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"}