Hi,
We had been using the android-database-sqlcipher 3.5.7 in our project to secure the db.
In order to support the 16Kb pagesize, we decided to move to sqlcipher-android 4.9.0.
We are facing issues in upgrade scenarios, when the app is trying to open the existing database, which was created using v3.5.7.
We are getting following error
Failed to open database ‘/data/user/0/com.konylabs.android/databases/TEST_DB_ENCRYPTED’.
android.database.sqlite.SQLiteException: file is not a database (code 26): , while compiling: SELECT COUNT(*) FROM sqlite_schema;
at net.zetetic.database.sqlcipher.SQLiteConnection.nativePrepareStatement(Native Method)
at net.zetetic.database.sqlcipher.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:973)
at net.zetetic.database.sqlcipher.SQLiteConnection.executeForLong(SQLiteConnection.java:628)
at net.zetetic.database.sqlcipher.SQLiteConnection.open(SQLiteConnection.java:240)
at net.zetetic.database.sqlcipher.SQLiteConnection.open(SQLiteConnection.java:202)
at net.zetetic.database.sqlcipher.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:475)
at net.zetetic.database.sqlcipher.SQLiteConnectionPool.open(SQLiteConnectionPool.java:189)
at net.zetetic.database.sqlcipher.SQLiteConnectionPool.open(SQLiteConnectionPool.java:181)
at net.zetetic.database.sqlcipher.SQLiteDatabase.openInner(SQLiteDatabase.java:1028)
at net.zetetic.database.sqlcipher.SQLiteDatabase.open(SQLiteDatabase.java:1013)
at net.zetetic.database.sqlcipher.SQLiteDatabase.openDatabase(SQLiteDatabase.java:840)
at net.zetetic.database.sqlcipher.SQLiteDatabase.openDatabase(SQLiteDatabase.java:812)
at net.zetetic.database.sqlcipher.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:929)
SQLiteDatabaseHook implementation in 3.5.2
public void preKey(SQLiteDatabase paramSQLiteDatabase){
paramSQLiteDatabase.rawExecSQL("PRAGMA cipher_default_kdf_iter = 4000");
}
public void postKey(SQLiteDatabase paramSQLiteDatabase){
}
We are using following code in th SQLiteDatabaseHook implementation in 4.9.0
public void preKey(SQLiteConnection sqLiteConnection) {
try {
sqLiteConnection.executeForLong("PRAGMA cipher_default_kdf_iter = 4000;", null, null);
} catch (Exception exception) {
exception.printStackTrace();
}
}
}
public void postKey(SQLiteConnection sqLiteConnection) {
try {
sqLiteConnection.execute("PRAGMA cipher_compatibility = 3;", null, null);
} catch (Exception exception) {
exception.printStackTrace();
}
}
}`
Any help is appreciated.
Hi @erraisahmad,
Try changing your preKey method to invoke execute instead of executeForLong. This works for me when querying a SQLCipher v3 database file from sqlcipher-android:
fun runSQLCipher(context: Context){
val filename = "foo.db"
val dbPath = context.getDatabasePath(filename)
if(!dbPath.exists()){
val inputStream = context.assets.open(filename)
val outputStream = FileOutputStream(dbPath)
val buffer = ByteArray(1024)
var length: Int
while ((inputStream.read(buffer).also { length = it }) > 0) {
outputStream.write(buffer, 0, length)
}
outputStream.flush()
outputStream.close()
inputStream.close()
}
System.loadLibrary("sqlcipher")
val hook: SQLiteDatabaseHook = object : SQLiteDatabaseHook {
override fun preKey(db: SQLiteConnection?) {
db?.execute("PRAGMA cipher_default_kdf_iter = 4000;", null, null)
}
override fun postKey(db: SQLiteConnection?) {
db?.execute("PRAGMA cipher_compatibility = 3;", null, null)
}
}
val db = SQLiteDatabase.openOrCreateDatabase(dbPath, "foo", null, null, hook)
val cursor = db?.query("SELECT * FROM t1;")
while(cursor != null && cursor.moveToNext()){
val a = cursor.getString(0)
val b = cursor.getString(1)
Log.i("SQLCIPHER", "a = $a, b = $b")
}
cursor?.close()
db?.close()
}
Thank you for your reply.
The recommendation worked with a small change. It worked with combination of PRAGMA cipher_migrate.
public void postKey(SQLiteConnection sqLiteConnection) {
try {
sqLiteConnection.execute("PRAGMA cipher_migrate;", null, null);
sqLiteConnection.execute("PRAGMA cipher_compatibility = 3;", null, null);
} catch (Exception exception) {
if(DEBUG) {
Log.d(TAG, " postKey PRAGMA statement execution Failed ");
exception.printStackTrace();
}
}
}
Thank you.
Hi @erraisahmad,
Running PRAGMA cipher_migrate will perform an in-place upgrade of the entire database to the latest file format. As such, you do not need to execute PRAGMA cipher_compatibility = 3 at all, you should remove that line.
Thank you @developernotes It really helped.
I am able to acheive the functionality.
I am seeing below exception in postkey method
android.database.sqlite.SQLiteException: unknown error (code 0): Queries can be performed using SQLiteDatabase query or rawQuery methods only.
2025-10-09 19:43:07.591 4201-4244 System.err com.konylabs.android W at net.zetetic.database.sqlcipher.SQLiteConnection.nativeExecute(Native Method)
2025-10-09 19:43:07.591 4201-4244 System.err com.konylabs.android W at net.zetetic.database.sqlcipher.SQLiteConnection.execute(SQLiteConnection.java:592)
2025-10-09 19:43:07.591 4201-4244 System.err com.konylabs.android W at com.konylabs.api.db.sqlcipher.KonySQLDatabase.postKey(KonySQLDatabase.java:207)
2025-10-09 19:43:07.591 4201-4244 System.err com.konylabs.android W at net.zetetic.database.sqlcipher.SQLiteConnection.open(SQLiteConnection.java:237)
2025-10-09 19:43:07.591 4201-4244 System.err com.konylabs.android W at net.zetetic.database.sqlcipher.SQLiteConnection.open(SQLiteConnection.java:202)
2025-10-09 19:43:07.591 4201-4244 System.err com.konylabs.android W at net.zetetic.database.sqlcipher.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:474)
2025-10-09 19:43:07.591 4201-4244 System.err com.konylabs.android W at net.zetetic.database.sqlcipher.SQLiteConnectionPool.open(SQLiteConnectionPool.java:188)
2025-10-09 19:43:07.591 4201-4244 System.err com.konylabs.android W at net.zetetic.database.sqlcipher.SQLiteConnectionPool.open(SQLiteConnectionPool.java:180)
2025-10-09 19:43:07.591 4201-4244 System.err com.konylabs.android W at net.zetetic.database.sqlcipher.SQLiteDatabase.openInner(SQLiteDatabase.java:1028)
2025-10-09 19:43:07.591 4201-4244 System.err com.konylabs.android W at net.zetetic.database.sqlcipher.SQLiteDatabase.open(SQLiteDatabase.java:1013)
2025-10-09 19:43:07.593 4201-4244 System.err com.konylabs.android W at net.zetetic.database.sqlcipher.SQLiteDatabase.openDatabase(SQLiteDatabase.java:840)
2025-10-09 19:43:07.593 4201-4244 System.err com.konylabs.android W at net.zetetic.database.sqlcipher.SQLiteDatabase.openDatabase(SQLiteDatabase.java:740)
2025-10-09 19:43:07.593 4201-4244 System.err com.konylabs.android W at com.konylabs.api.db.sqlcipher.KonySQLDatabase.openDatabase(KonySQLDatabase.java:111)
The error message explicitly tells us to use SQLiteDatabase methods whereas the postkey method argument is SQLIteConnection.
Can you please help me reagarding this exception
What SQL command are you trying to run in the postKey event that causes the exception?
Hi @developernotes
I am running only a PRAGMA command in post key.
public void postKey(SQLiteConnection sqLiteConnection) {
try {
sqLiteConnection.execute("PRAGMA cipher_migrate;", null, null);
} catch (Exception exception) {
if(DEBUG) {
Log.d(TAG, " postKey PRAGMA statement execution Failed ");
exception.printStackTrace();
}
}
}
I don’t see any exception in preKey where I am executing another PRAGMA.
public void preKey(SQLiteConnection sqLiteConnection) {
try {
sqLiteConnection.execute("PRAGMA cipher_default_kdf_iter = 4000;", null, null);
} catch (Exception exception) {
exception.printStackTrace();
}
}
}
Its only occurring for postKey
Hi @erraisahmad,
Here is an example of performing the PRAGMA cipher_migrate command within the postKey event.
Hi @developernotes
net.zetetic.database.sqlcipher.SQLiteNotADatabaseException: file is not a database (code 26): , while compiling: PRAGMA journal_mode with latest version 4.12
Hi @R_Rajesh,
Please provide additional details regarding your situation, and if it’s unrelated to the topic of this thread, please consider creating a separate posting.