apache/cassandra · error · ConfigurationException

Cannot use abstract class

Error message

Cannot use abstract class '%s' as %s.

What it means

Same reflective construction path (constructorForName/Class.newInstance): if instantiation fails with InstantiationException, the configured class is abstract or an interface, so a ConfigurationException 'Cannot use abstract class ... as %s' is thrown. A catch-all also unwraps exceptions thrown by the constructor itself, rethrowing a nested ConfigurationException directly.

Solutions

  1. Configure a concrete (non-abstract) implementation class of the plugin interface
  2. If the chained cause is a constructor exception, fix the root problem it reports
  3. Verify with `javap` or IDE that the class is concrete and instantiable
  4. Upgrade custom code if it became abstract after a refactor

Example fix

// before
class_name: org.apache.cassandra.security.AbstractCryptoProvider  // abstract
// after
class_name: org.apache.cassandra.security.DefaultCryptoProvider
Defensive patterns

Strategy: validation

Validate before calling

boolean isConcreteInstantiable(String cn) {
    try { Class<?> c = Class.forName(cn);
          return !c.isInterface() && !java.lang.reflect.Modifier.isAbstract(c.getModifiers()); }
    catch (Throwable t) { return false; }
}
// guard: if (!isConcreteInstantiable(className)) failFast();

Try / catch

try {
    Object plugin = FBUtilities.constructorForName(className, readable);
} catch (ConfigurationException e) {
    if (e.getCause() instanceof ConfigurationException)
        logger.error("Plugin constructor reported config error", e.getCause());
    else if (e.getMessage() != null && e.getMessage().contains("abstract"))
        logger.error("Configure a concrete implementation, not " + className);
    throw e;
}

Prevention

When it happens

Trigger: Configuring an abstract class or interface as a pluggable implementation, or the plugin's constructor throwing any exception during newInstance() (checked exceptions are propagated by Class.newInstance()).

Common situations: Pointing config at a base/abstract class instead of a concrete implementation; interface name typo-direction (listing the interface rather than an impl); plugin constructor throwing due to bad init (e.g. cannot open file).

Understand the failure class

Background: "NotImplementedError: Subclasses should override this method" / "must be implemented" — abstract method errors explained — this error's family across 40 libraries.

Related errors


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

Appendix: source

Thrown at src/java/org/apache/cassandra/utils/FBUtilities.java:908

    public static <T> T construct(String classname, String readable, Class<T> expectedType) throws ConfigurationException
    {
        Class<? extends T> cls = FBUtilities.classForNameWithoutInitialization(classname, readable, expectedType);
        return construct(cls, classname, readable);
    }

    private static <T> T construct(Class<? extends T> cls, String classname, String readable) throws ConfigurationException
    {
        try
        {
            return cls.newInstance();
        }
        catch (IllegalAccessException e)
        {
            throw new ConfigurationException(String.format("Default constructor for %s class '%s' is inaccessible.", readable, classname));
        }
        catch (InstantiationException e)
        {
            throw new ConfigurationException(String.format("Cannot use abstract class '%s' as %s.", classname, readable));
        }
        catch (Exception e)
        {
            // Catch-all because Class.newInstance() "propagates any exception thrown by the nullary constructor, including a checked exception".
            if (e.getCause() instanceof ConfigurationException)
                throw (ConfigurationException)e.getCause();
            throw new ConfigurationException(String.format("Error instantiating %s class '%s'.", readable, classname), e);
        }
    }

    public static <T> NavigableSet<T> singleton(T column, Comparator<? super T> comparator)
    {
        NavigableSet<T> s = new TreeSet<T>(comparator);
        s.add(column);
        return s;
    }

    public static <T> NavigableSet<T> emptySortedSet(Comparator<? super T> comparator)

View on GitHub (pinned to 88fd0f6a0e)