Getting file not a database exception when trying to attach database

try {
            getWritableDatabase(mPassword)
        } catch (e: SQLiteException) {
            encrypt(mPassword.toByteArray())
            getWritableDatabase(mPassword)
        }


    private fun encrypt(passphrase: ByteArray) {
        val originalFile = context.getDatabasePath(DB_NAME)
        if (originalFile.exists()) {
            val newFilePath = originalFile.parent
            val newFile = File(newFilePath, "sqlcipherutils.db")

            // get database version from existing database
            val databaseVersion = SQLiteDatabase.openDatabase(
                originalFile.absolutePath,
                "",
                null,
                SQLiteDatabase.OPEN_READWRITE
            ).use { database ->
                database.version
            }

            SQLiteDatabase.openOrCreateDatabase(
                newFile.absolutePath, passphrase, null
            ).use {
                it.rawExecSQL( **

> //line 164

**
                    "ATTACH DATABASE '${originalFile.absolutePath}' AS sqlcipher4 KEY '${
                        String(
                            mPassword
                        )
                    }'"
                )
                it.rawExecSQL("SELECT sqlcipher_export('main', 'sqlcipher4')")
                it.rawExecSQL("DETACH DATABASE sqlcipher4")
                it.version = databaseVersion
            }
            originalFile.delete()
            newFile.renameTo(originalFile)
        } else {
            throw FileNotFoundException(originalFile.absolutePath.toString() + " not found")
        }
    }

Caused by: net.sqlcipher.database.SQLiteException: file is not a database
at net.sqlcipher.database.SQLiteDatabase.native_rawExecSQL(Native Method)
at net.sqlcipher.database.SQLiteDatabase.rawExecSQL(SQLiteDatabase.java:2455)
at .database.utils.DbHelper.encrypt(DbHelper.kt:164)

Hi @jbp,

It appears from your code that originalFile already exists and is not encrypted when you query for the version. You are then trying to open a database connection to newFile, and attaching originalFile but providing a key to originalFile which will not work as it is not encrypted. You may want to review the documentation on cipher_migrate [1], the convenience function which will allow you to encrypt a plaintext SQLite database among other operations.


  1. SQLCipher API - Zetetic ↩︎