apache/cassandra · critical · RuntimeException

couldn't load cipher factory

Error message

couldn't load cipher factory

What it means

The CipherFactory constructor resolves the configured TDE key provider class via reflection and instantiates it with the TransparentDataEncryptionOptions. Any failure (class missing, no matching constructor, constructor throwing) is wrapped in a RuntimeException with this message.

Solutions

  1. Check transparent_data_encryption_options.key_provider.class_name spelling; default is org.apache.cassandra.security.JKSKeyProvider.
  2. Ensure the class implements org.apache.cassandra.security.KeyProvider and has a public constructor taking TransparentDataEncryptionOptions.
  3. If using a custom provider, add its JAR to the classpath (lib/ or classpath config).
  4. Inspect the wrapped cause for the underlying error (ClassNotFoundException vs constructor exception).

Example fix

// before (cassandra.yaml)
transparent_data_encryption_options:
  key_provider:
    class_name: com.example.MyKeyProviser
// after
transparent_data_encryption_options:
  key_provider:
    class_name: com.example.MyKeyProvider
Defensive patterns

Strategy: validation

Validate before calling

String cn = tdeOptions.key_provider.class_name;
Class<?> c = Class.forName(cn);
if (!KeyProvider.class.isAssignableFrom(c)) throw new IllegalArgumentException(cn + " is not a KeyProvider");
c.getConstructor(TransparentDataEncryptionOptions.class); // throws NoSuchMethodException early

Try / catch

try {
    new CipherFactory(tdeOptions);
} catch (RuntimeException e) {
    throw new ConfigurationException("Invalid key_provider settings: " + e.getCause(), e);
}

Prevention

When it happens

Trigger: new CipherFactory(options) where options.key_provider.class_name does not exist on the classpath, is not a KeyProvider, has no (TransparentDataEncryptionOptions) constructor, or its constructor throws (e.g. bad JCEKS path).

Common situations: Typo in cipher/key_provider class_name in cassandra.yaml, custom key provider JAR not shipped in lib/, key provider constructor failing to open the keystore file.

Related errors


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

Appendix: source

Thrown at src/java/org/apache/cassandra/security/CipherFactory.java:82

    private final int ivLength;
    private final KeyProvider keyProvider;

    public CipherFactory(TransparentDataEncryptionOptions options)
    {
        logger.info("initializing CipherFactory");
        ivLength = options.iv_length;

        try
        {
            secureRandom = SecureRandom.getInstance("SHA1PRNG");
            Class<? extends KeyProvider> keyProviderClass =
                FBUtilities.classForNameWithoutInitialization(options.key_provider.class_name, "key provider", KeyProvider.class);
            Constructor<? extends KeyProvider> ctor = keyProviderClass.getConstructor(TransparentDataEncryptionOptions.class);
            keyProvider = ctor.newInstance(options);
        }
        catch (Exception e)
        {
            throw new RuntimeException("couldn't load cipher factory", e);
        }

        cache = Caffeine.newBuilder() // by default cache is unbounded
                .maximumSize(64) // a value large enough that we should never even get close (so nothing gets evicted)
                .executor(ImmediateExecutor.INSTANCE)
                .removalListener((key, value, cause) ->
                {
                    // maybe reload the key? (to avoid the reload being on the user's dime)
                    logger.info("key {} removed from cipher key cache", key);
                })
                .build(alias ->
                       {
                           logger.info("loading secret key for alias {}", alias);
                           return keyProvider.getSecretKey(alias);
                       });
    }

    public Cipher getEncryptor(String transformation, String keyAlias) throws IOException

View on GitHub (pinned to 88fd0f6a0e)