{"record":{"id":"c196720470a6ca3c","repo":"apache/cassandra","slug":"couldn-t-load-cipher-factory","errorCode":null,"errorMessage":"couldn't load cipher factory","messagePattern":"couldn't load cipher factory","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"critical","filePath":"src/java/org/apache/cassandra/security/CipherFactory.java","lineNumber":82,"sourceCode":"    private final int ivLength;\n    private final KeyProvider keyProvider;\n\n    public CipherFactory(TransparentDataEncryptionOptions options)\n    {\n        logger.info(\"initializing CipherFactory\");\n        ivLength = options.iv_length;\n\n        try\n        {\n            secureRandom = SecureRandom.getInstance(\"SHA1PRNG\");\n            Class<? extends KeyProvider> keyProviderClass =\n                FBUtilities.classForNameWithoutInitialization(options.key_provider.class_name, \"key provider\", KeyProvider.class);\n            Constructor<? extends KeyProvider> ctor = keyProviderClass.getConstructor(TransparentDataEncryptionOptions.class);\n            keyProvider = ctor.newInstance(options);\n        }\n        catch (Exception e)\n        {\n            throw new RuntimeException(\"couldn't load cipher factory\", e);\n        }\n\n        cache = Caffeine.newBuilder() // by default cache is unbounded\n                .maximumSize(64) // a value large enough that we should never even get close (so nothing gets evicted)\n                .executor(ImmediateExecutor.INSTANCE)\n                .removalListener((key, value, cause) ->\n                {\n                    // maybe reload the key? (to avoid the reload being on the user's dime)\n                    logger.info(\"key {} removed from cipher key cache\", key);\n                })\n                .build(alias ->\n                       {\n                           logger.info(\"loading secret key for alias {}\", alias);\n                           return keyProvider.getSecretKey(alias);\n                       });\n    }\n\n    public Cipher getEncryptor(String transformation, String keyAlias) throws IOException","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/security/CipherFactory.java#L64-L100","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Check transparent_data_encryption_options.key_provider.class_name spelling; default is org.apache.cassandra.security.JKSKeyProvider.","Ensure the class implements org.apache.cassandra.security.KeyProvider and has a public constructor taking TransparentDataEncryptionOptions.","If using a custom provider, add its JAR to the classpath (lib/ or classpath config).","Inspect the wrapped cause for the underlying error (ClassNotFoundException vs constructor exception)."],"exampleFix":"// before (cassandra.yaml)\ntransparent_data_encryption_options:\n  key_provider:\n    class_name: com.example.MyKeyProviser\n// after\ntransparent_data_encryption_options:\n  key_provider:\n    class_name: com.example.MyKeyProvider","handlingStrategy":"validation","validationCode":"String cn = tdeOptions.key_provider.class_name;\nClass<?> c = Class.forName(cn);\nif (!KeyProvider.class.isAssignableFrom(c)) throw new IllegalArgumentException(cn + \" is not a KeyProvider\");\nc.getConstructor(TransparentDataEncryptionOptions.class); // throws NoSuchMethodException early","typeGuard":null,"tryCatchPattern":"try {\n    new CipherFactory(tdeOptions);\n} catch (RuntimeException e) {\n    throw new ConfigurationException(\"Invalid key_provider settings: \" + e.getCause(), e);\n}","preventionTips":["Copy-paste fully-qualified class names, don't hand-type them","Ship custom key provider JARs and verify with a startup smoke test","Keep default JKSKeyProvider unless a custom provider is truly needed"],"tags":["encryption","reflection","class-not-found","configuration"],"backgroundTag":"class-not-found","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"}