apache/cassandra · error · ConfigurationException

No valid constructor found for class <class_name>

Error message

No valid constructor found for class <class_name>

What it means

ParameterizedClass.newInstance() reflectively instantiates a configured provider/impl class from its class_name. After trying constructors matching the configured parameters and then the no-arg constructor, if none can be found it throws ConfigurationException. It means the configured class exists but exposes no constructor Cassandra can call.

Source

Thrown at src/java/org/apache/cassandra/config/ParameterizedClass.java:128

        // Verify the resolved class is the expected extension type before it is initialized/instantiated. Done once,
        // after the package search, so a wrong-type match under an earlier search package does not abort the search
        // before a valid class under a later package is found.
        if (expectedType != null && !expectedType.isAssignableFrom(providerClass))
            throw new ConfigurationException("Invalid parameterized class " + providerClass.getName() +
                                             ": must extend or implement " + expectedType.getName());

        try
        {
            Constructor<?> mapConstructor = filterConstructor(providerClass, c -> c.getParameterTypes().length == 1 && c.getParameterTypes()[0].equals(Map.class));
            if (mapConstructor != null)
                return (K) mapConstructor.newInstance(parameterizedClass.parameters == null ? Collections.emptyMap() : parameterizedClass.parameters);

            // Falls-back to no-arg constructor
            Constructor<?> noArgsConstructor = filterConstructor(providerClass, c -> c.getParameterTypes().length == 0);
            if (noArgsConstructor != null)
                return (K) noArgsConstructor.newInstance();

            throw new ConfigurationException("No valid constructor found for class " + parameterizedClass.class_name);
        }
        catch (IllegalAccessException | InstantiationException | ExceptionInInitializerError e)
        {
            throw new ConfigurationException("Unable to instantiate parameterized class " + parameterizedClass.class_name, e);
        }
        catch (InvocationTargetException e)
        {
            Throwable cause = e.getCause();
            String error = "Failed to instantiate class " + parameterizedClass.class_name +
                           (cause.getMessage() != null ? ": " + cause.getMessage() : "");
            throw new ConfigurationException(error, cause);
        }
    }

    private static Constructor<?> filterConstructor(Class<?> providerClass, Predicate<Constructor<?>> filter)
    {
        for (Constructor<?> constructor : providerClass.getDeclaredConstructors())
        {

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Add a public no-arg constructor to the configured class
  2. Ensure any required parameters in the ParameterizedClass map match a declared constructor's parameter types
  3. Verify the class_name points at a concrete, instantiable class (not abstract/interface)
  4. Check the fully-qualified class name is correct and the class is on the classpath

Example fix

// before
public class MyProvider implements IProvider {
    public MyProvider(String requiredArg) { ... }
}
// after
public class MyProvider implements IProvider {
    public MyProvider() { ... }
    public MyProvider(String requiredArg) { ... }
}
Defensive patterns

Strategy: validation

Validate before calling

Class<?> c = Class.forName(className);
boolean ok = !c.isInterface() && !java.lang.reflect.Modifier.isAbstract(c.getModifiers())
    && java.util.Arrays.stream(c.getDeclaredConstructors())
        .anyMatch(k -> k.getParameterCount() == 0);
if (!ok) throw new IllegalStateException(className + " needs a public no-arg constructor");

Type guard

static boolean hasUsableConstructor(String className) {
    try {
        Class<?> c = Class.forName(className);
        return !c.isInterface() && !java.lang.reflect.Modifier.isAbstract(c.getModifiers())
            && java.util.Arrays.stream(c.getDeclaredConstructors())
                .anyMatch(k -> k.getParameterCount() == 0);
    } catch (ClassNotFoundException e) { return false; }
}

Try / catch

try { K instance = ParameterizedClass.newInstance(cls); }
catch (ConfigurationException e) { log.error("Bad provider class: " + e.getMessage()); throw e; }

Prevention

When it happens

Trigger: Setting a config key like commitlog_sync, key_cache_size, or a custom provider class_name to a class that has no no-arg constructor and no constructor matching the supplied parameters.

Common situations: Implementing a custom ICommitLogWrite/encryption provider with only a parameterized constructor; renaming constructors to require arguments; pointing class_name at an abstract class or interface with no usable constructor.

Related errors


AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10). Data as JSON: /api/errors/4722246f1b9b427f. Report an issue: GitHub.