{"record":{"id":"781cb2d21530d5fa","repo":"greenrobot/greenDAO","slug":"using-an-encrypted-database-requires-sqlcipher-ma","errorCode":null,"errorMessage":"Using an encrypted database requires SQLCipher, make sure to add it to dependencies: https://greenrobot.org/greendao/documentation/database-encryption/","messagePattern":"Using an encrypted database requires SQLCipher, make sure to add it to dependencies: https://greenrobot\\.org/greendao/documentation/database-encryption/","errorType":"exception","errorClass":"DaoException","httpStatus":null,"severity":"error","filePath":"DaoCore/src/main/java/org/greenrobot/greendao/database/DatabaseOpenHelper.java","lineNumber":145,"sourceCode":"     * Override this if you do not want to depend on {@link SQLiteDatabase}.\n     */\n    public void onOpen(Database db) {\n        // Do nothing by default\n    }\n\n    interface EncryptedHelper {\n        Database getEncryptedReadableDb(String password);\n        Database getEncryptedReadableDb(char[] password);\n        Database getEncryptedWritableDb(String password);\n        Database getEncryptedWritableDb(char[] password);\n    }\n\n    private EncryptedHelper checkEncryptedHelper() {\n        if (encryptedHelper == null) {\n            try {\n                Class.forName(\"net.sqlcipher.database.SQLiteOpenHelper\");\n            } catch (ClassNotFoundException e) {\n                throw new DaoException(\"Using an encrypted database requires SQLCipher, \" +\n                        \"make sure to add it to dependencies: \" +\n                        \"https://greenrobot.org/greendao/documentation/database-encryption/\");\n            }\n\n            // Avoid referencing SqlCipherEncryptedHelper to avoid\n            // \"Rejecting re-init on previously-failed class java.lang.NoClassDefFoundError\" logs\n            // if SQLCipher is not in classpath.\n            try {\n                Class<?> helperClass = Class.forName(\n                        \"org.greenrobot.greendao.database.SqlCipherEncryptedHelper\");\n                Constructor<?> constructor = helperClass.getConstructor(\n                        DatabaseOpenHelper.class, Context.class, String.class, int.class, boolean.class);\n                encryptedHelper = (EncryptedHelper) constructor.newInstance(\n                        this, context, name, version, loadSQLCipherNativeLibs);\n            } catch (Exception e) {\n                throw new DaoException(e);\n            }\n        }","sourceCodeStart":127,"sourceCodeEnd":163,"githubUrl":"https://github.com/greenrobot/greenDAO/blob/0bbb338e17c4cf28aba5aae62d42f73f50186157/DaoCore/src/main/java/org/greenrobot/greendao/database/DatabaseOpenHelper.java#L127-L163","documentation":"DatabaseOpenHelper.checkEncryptedHelper() verifies at runtime that net.sqlcipher.database.SQLiteOpenHelper is on the classpath before creating an encrypted database. When an encrypted helper is requested but SQLCipher is not a dependency, this DaoException is thrown instead of failing later with NoClassDefFoundError.","triggerScenarios":"Calling helper.getEncryptedWritableDb(password) / getEncryptedReadableDb(...) (via encryptedHelper) without net.zetetic:android-database-sqlcipher (or the new sqlcipher-android artifact) in the dependencies.","commonSituations":"Developers add greendao, set an encryption password in code, but forget the SQLCipher Gradle dependency or ProGuard rules stripping it; or migrate from unencrypted to encrypted DB without updating dependencies.","solutions":["Add SQLCipher to dependencies, e.g. implementation 'net.zetetic:android-database-sqlcipher:4.5.4' (or 'net.zetetic:sqlcipher-android'), plus androidx.sqlite.","Replace the standard SQLiteDatabase factory wiring so greendao uses the encrypted helper only when intended.","If you did not intend encryption, call getWritableDatabase() instead of getEncryptedWritableDb(...).","After adding the dependency, sync Gradle and verify the SQLCipher classes survive R8/ProGuard (keep rules for net.sqlcipher.**)."],"exampleFix":"// build.gradle: before\ndependencies {\n    implementation 'org.greenrobot:greendao:3.3.0'\n}\n// after\ndependencies {\n    implementation 'org.greenrobot:greendao:3.3.0'\n    implementation 'net.zetetic:android-database-sqlcipher:4.5.4'\n    implementation 'androidx.sqlite:sqlite:2.4.0'\n}","handlingStrategy":"fallback","validationCode":"private boolean sqlCipherAvailable() {\n    try {\n        Class.forName(\"net.sqlcipher.database.SQLiteOpenHelper\");\n        return true;\n    } catch (ClassNotFoundException e) {\n        return false;\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    db = helper.getEncryptedWritableDb(password);\n} catch (DaoException e) {\n    throw new IllegalStateException(\"Add net.zetetic:android-database-sqlcipher to dependencies\", e);\n}","preventionTips":["Add the SQLCipher dependency before using getEncryptedWritableDb/getEncryptedReadableDb","Keep SQLCipher classes from being stripped by R8/ProGuard (keep net.sqlcipher.**)","If encryption is not required, use getWritableDatabase()/getReadableDatabase() instead"],"tags":["database","encryption","sqlcipher","missing-dependency"],"backgroundTag":"missing-optional-dependency","analyzedSha":"0bbb338e17c4cf28aba5aae62d42f73f50186157","analyzedAt":"2026-09-08T03:22:36.050Z","contentChangedAt":"2026-09-08T03:22:36.050Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}