apache/cassandra · error · ConfigurationException
Invalid class ' ': must extend or implement
Error message
Invalid %s class '%s': must extend or implement %s
What it means
classForNameWithoutInitialization loads a class without running its static initializers and verifies it extends/implements the expected base type. If the loaded class is not assignable to expectedType, a ConfigurationException reports the type mismatch with the required interface name. This guards pluggable configuration points against wrong types.
Solutions
- Point the config at a class that actually implements/extends the required type (named in the message)
- Fix your custom class to implement the expected interface
- Check for similarly-named classes from different plugin families and pick the right one
- Recompile/deploy the updated custom jar on all nodes
Example fix
// before ssl_factory: com.example.MyAuditLogger // wrong type // after ssl_factory: com.example.MySslContextFactory implements org.apache.cassandra.security.ISslContextFactory
Defensive patterns
Strategy: validation
Validate before calling
boolean isAssignable(String cn, Class<?> expected) {
try { return expected.isAssignableFrom(Class.forName(cn, false, Thread.currentThread().getContextClassLoader())); }
catch (Throwable t) { return false; }
}
// before config load: if (!isAssignable(sslFactoryName, ISslContextFactory.class)) failFast(); Type guard
boolean implementsPlugin(String cn, Class<?> expected) {
try { return expected.isAssignableFrom(Class.forName(cn, false, Thread.currentThread().getContextClassLoader())); }
catch (Throwable t) { return false; }
} Try / catch
try {
config.load();
} catch (ConfigurationException e) {
if (e.getMessage() != null && e.getMessage().contains("must extend or implement"))
logger.error("Configured class has the wrong type — fix class name in config", e);
throw e;
} Prevention
- Cross-check the config value against the interface documented for that config key
- Avoid copy-pasting class names between different plugin config sections
- Write unit tests that load configured plugin classes via the same code path
- Implement the exact interface required, not a similarly-named one
When it happens
Trigger: Configuring a class name for a pluggable component (e.g. SSL factory, crypto provider, commit log archiver) that exists but implements the wrong interface — classForNameWithoutInitialization(name, readable, expectedType, ...) hits the isAssignableFrom check.
Common situations: Implementing the wrong interface in custom code; pointing a factory option at a class of a different plugin kind; copy-pasting a class name between config sections (e.g. audit logger name used as ssl_factory); refactor moved functionality to a new interface.
Related errors
- Could not create memtable factory for class
- Failed to transfer field
- Invalid parameterized class <providerClass.getName()>: must…
- Unable to create an instance of crypto provider for
- Unable to create an instance of the compression service…
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/638be91b645534d9.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/utils/FBUtilities.java:819
* Loads a class without initializing it, then verifies it extends or implements the expected base type.
*
* @return The Class for the given name.
* @param classname Fully qualified classname.
* @param readable Descriptive noun for the role the class plays.
* @param expectedType Required superclass or interface.
* @param classLoader ClassLoader to use.
* @throws ConfigurationException If the class cannot be found or is not assignable to {@code expectedType}.
*/
public static <T> Class<? extends T> classForNameWithoutInitialization(String classname,
String readable,
Class<T> expectedType,
ClassLoader classLoader) throws ConfigurationException
{
try
{
Class<?> klass = Class.forName(classname, false, classLoader);
if (!expectedType.isAssignableFrom(klass))
throw new ConfigurationException(String.format("Invalid %s class '%s': must extend or implement %s",
readable,
classname,
expectedType.getName()));
return klass.asSubclass(expectedType);
}
catch (ClassNotFoundException | NoClassDefFoundError e)
{
throw new ConfigurationException(String.format("Unable to find %s class '%s'", readable, classname), e);
}
}
/**
* Constructs an instance of the given class, which must have a no-arg or default constructor.
* @param classname Fully qualified classname.
* @param readable Descriptive noun for the role the class plays.
* @throws ConfigurationException If the class cannot be found.
*/
public static <T> T instanceOrConstruct(String classname, String readable) throws ConfigurationExceptionView on GitHub (pinned to 88fd0f6a0e)