greenrobot/greenDAO · error · DaoException

Using an encrypted database requires SQLCipher, make sure…

Error message

Using an encrypted database requires SQLCipher, make sure to add it to dependencies: https://greenrobot.org/greendao/documentation/database-encryption/

What it means

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.

Solutions

  1. Add SQLCipher to dependencies, e.g. implementation 'net.zetetic:android-database-sqlcipher:4.5.4' (or 'net.zetetic:sqlcipher-android'), plus androidx.sqlite.
  2. Replace the standard SQLiteDatabase factory wiring so greendao uses the encrypted helper only when intended.
  3. If you did not intend encryption, call getWritableDatabase() instead of getEncryptedWritableDb(...).
  4. After adding the dependency, sync Gradle and verify the SQLCipher classes survive R8/ProGuard (keep rules for net.sqlcipher.**).

Example fix

// build.gradle: before
dependencies {
    implementation 'org.greenrobot:greendao:3.3.0'
}
// after
dependencies {
    implementation 'org.greenrobot:greendao:3.3.0'
    implementation 'net.zetetic:android-database-sqlcipher:4.5.4'
    implementation 'androidx.sqlite:sqlite:2.4.0'
}
Defensive patterns

Strategy: fallback

Validate before calling

private boolean sqlCipherAvailable() {
    try {
        Class.forName("net.sqlcipher.database.SQLiteOpenHelper");
        return true;
    } catch (ClassNotFoundException e) {
        return false;
    }
}

Try / catch

try {
    db = helper.getEncryptedWritableDb(password);
} catch (DaoException e) {
    throw new IllegalStateException("Add net.zetetic:android-database-sqlcipher to dependencies", e);
}

Prevention

When it happens

Trigger: Calling helper.getEncryptedWritableDb(password) / getEncryptedReadableDb(...) (via encryptedHelper) without net.zetetic:android-database-sqlcipher (or the new sqlcipher-android artifact) in the dependencies.

Common situations: 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.

Understand the failure class

Background: "X is not installed. Please install it with pip install Y": missing optional dependency errors — ImportError/ValueError raised when a library's optional extra was never installed — this error's family across 22 libraries.

Related errors


AI-assisted analysis of greenrobot/greenDAO@0bbb338e17 (2026-09-08). Data as JSON: /api/errors/781cb2d21530d5fa. Report an issue: GitHub.

Appendix: source

Thrown at DaoCore/src/main/java/org/greenrobot/greendao/database/DatabaseOpenHelper.java:145

     * Override this if you do not want to depend on {@link SQLiteDatabase}.
     */
    public void onOpen(Database db) {
        // Do nothing by default
    }

    interface EncryptedHelper {
        Database getEncryptedReadableDb(String password);
        Database getEncryptedReadableDb(char[] password);
        Database getEncryptedWritableDb(String password);
        Database getEncryptedWritableDb(char[] password);
    }

    private EncryptedHelper checkEncryptedHelper() {
        if (encryptedHelper == null) {
            try {
                Class.forName("net.sqlcipher.database.SQLiteOpenHelper");
            } catch (ClassNotFoundException e) {
                throw new DaoException("Using an encrypted database requires SQLCipher, " +
                        "make sure to add it to dependencies: " +
                        "https://greenrobot.org/greendao/documentation/database-encryption/");
            }

            // Avoid referencing SqlCipherEncryptedHelper to avoid
            // "Rejecting re-init on previously-failed class java.lang.NoClassDefFoundError" logs
            // if SQLCipher is not in classpath.
            try {
                Class<?> helperClass = Class.forName(
                        "org.greenrobot.greendao.database.SqlCipherEncryptedHelper");
                Constructor<?> constructor = helperClass.getConstructor(
                        DatabaseOpenHelper.class, Context.class, String.class, int.class, boolean.class);
                encryptedHelper = (EncryptedHelper) constructor.newInstance(
                        this, context, name, version, loadSQLCipherNativeLibs);
            } catch (Exception e) {
                throw new DaoException(e);
            }
        }

View on GitHub (pinned to 0bbb338e17)