{"record":{"id":"3e66438f4898cd87","repo":"apache/cassandra","slug":"invalid-parameterized-class-providerclass-getname","errorCode":null,"errorMessage":"Invalid parameterized class <providerClass.getName()>: must extend or implement <expectedType.getName()>","messagePattern":"Invalid parameterized class <providerClass\\.getName\\(\\)>: must extend or implement <expectedType\\.getName\\(\\)>","errorType":"validation","errorClass":"ConfigurationException","httpStatus":null,"severity":"critical","filePath":"src/java/org/apache/cassandra/config/ParameterizedClass.java","lineNumber":114,"sourceCode":"            }\n            catch (ClassNotFoundException | NoClassDefFoundError e)\n            {\n                //no-op\n            }\n        }\n\n        if (providerClass == null)\n        {\n            String pkgList = '[' + searchPackages.stream().map(p -> '\"' + p + '\"').collect(Collectors.joining(\",\")) + ']';\n            String error = \"Unable to find class \" + parameterizedClass.class_name + \" in packages \" + pkgList;\n            throw new ConfigurationException(error);\n        }\n\n        // Verify the resolved class is the expected extension type before it is initialized/instantiated. Done once,\n        // after the package search, so a wrong-type match under an earlier search package does not abort the search\n        // before a valid class under a later package is found.\n        if (expectedType != null && !expectedType.isAssignableFrom(providerClass))\n            throw new ConfigurationException(\"Invalid parameterized class \" + providerClass.getName() +\n                                             \": must extend or implement \" + expectedType.getName());\n\n        try\n        {\n            Constructor<?> mapConstructor = filterConstructor(providerClass, c -> c.getParameterTypes().length == 1 && c.getParameterTypes()[0].equals(Map.class));\n            if (mapConstructor != null)\n                return (K) mapConstructor.newInstance(parameterizedClass.parameters == null ? Collections.emptyMap() : parameterizedClass.parameters);\n\n            // Falls-back to no-arg constructor\n            Constructor<?> noArgsConstructor = filterConstructor(providerClass, c -> c.getParameterTypes().length == 0);\n            if (noArgsConstructor != null)\n                return (K) noArgsConstructor.newInstance();\n\n            throw new ConfigurationException(\"No valid constructor found for class \" + parameterizedClass.class_name);\n        }\n        catch (IllegalAccessException | InstantiationException | ExceptionInInitializerError e)\n        {\n            throw new ConfigurationException(\"Unable to instantiate parameterized class \" + parameterizedClass.class_name, e);","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/config/ParameterizedClass.java#L96-L132","documentation":"After resolving a configured class by name, ParameterizedClass.newInstance verifies (once, after package search) that the resolved class extends or implements the expected type. If it exists but has the wrong type (e.g. a class configured as an authenticator that doesn't implement IAuthenticator), ConfigurationException is thrown naming both the found class and required type.","triggerScenarios":"Pointing a config slot (authenticator, authorizer, seed provider, encryptor, etc.) at a class that exists on the classpath but implements the wrong interface, e.g. swapping authenticator and authorizer class names, or configuring a base/abstract or unrelated class.","commonSituations":"Copy-pasting the wrong FQCN between config slots; a custom class refactored to no longer implement the required interface; upgrading Cassandra where the interface contract changed; accidentally configuring an internal utility class.","solutions":["Make the configured class implement/extend the expected type named in the message.","Correct the config to reference the class intended for that slot.","If the interface changed in an upgrade, update or recompile the custom class against the new API."],"exampleFix":"// before\nauthenticator:\n  class_name: com.example.MyAuthorizer  # wrong type\n// after\nauthenticator:\n  class_name: com.example.MyAuthenticator implements IAuthenticator","handlingStrategy":"validation","validationCode":"Class<?> c = Class.forName(fqcn, false, loader);\nif (!expectedType.isAssignableFrom(c))\n    throw new ConfigurationException(fqcn + \" does not implement \" + expectedType.getName());","typeGuard":"static boolean implementsExpected(String fqcn, Class<?> expected) throws ClassNotFoundException { return expected.isAssignableFrom(Class.forName(fqcn, false, ParameterizedClass.class.getClassLoader())); }","tryCatchPattern":"try { ParameterizedClass.newInstance(def, expectedType, packages); } catch (ConfigurationException e) { LOG.error(\"wrong type for slot {}: {}\", def.class_name, e.getMessage()); throw e; }","preventionTips":["Verify the class implements the interface named in the config slot before deploying","Add an interface-conformance unit test for custom classes","Recompile custom classes against the target Cassandra version's interfaces","Don't reuse one FQCN across different config slots with different expected types"],"tags":["config","type-mismatch","classpath"],"backgroundTag":"type-mismatch","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}