Attempt to write a readonly database… but I'm not

I have a read-only database connection. Sometimes, when reading data from the database with a SELECT query, it throws a SQLiteReadOnlyDatabaseException.

I open the connection like this:

  • How to get all files from assets folder
  • How to get context for BaseAdapter in Android
  • How to pop fragment off backstack
  • Android Studio “Unable to save plugin settings”
  • SQLite Query in Android to count rows
  • 'adb devices' showing dummy device
  • return SQLiteDatabase.openDatabase(path, null, SQLiteDatabase.OPEN_READONLY);

    The query is:

    Select * FROM BudgetVersions WHERE entityId = ?

    I read data from the database using db.rawQuery(), like this:

    String query = ...;
    Cursor c = db.rawQuery(query, new String[]{ activeBudgetId });
    try {
        if (c.moveToFirst()) {            
            bv.versionName = c.getString(c.getColumnIndexOrThrow("versionName"));
            return bv;
        } else {
            return null;
    } finally {

    Very rarely, I get a crash like this, inside the call to c.moveToFirst():

    Caused by: android.database.sqlite.SQLiteReadOnlyDatabaseException: attempt to write a readonly database (code 776)
    at android.database.sqlite.SQLiteConnection.nativeExecuteForCursorWindow(Native Method)
    at android.database.sqlite.SQLiteConnection.executeForCursorWindow(
    at android.database.sqlite.SQLiteSession.executeForCursorWindow(
    at android.database.sqlite.SQLiteQuery.fillWindow(
    at android.database.sqlite.SQLiteCursor.fillWindow(
    at android.database.sqlite.SQLiteCursor.getCount(
    at android.database.AbstractCursor.moveToPosition(
    at android.database.AbstractCursor.moveToFirst(

    As a workaround, I could try using a writable database connection instead, but I’d like to know why the crash is happening.

    The table I’m reading from is a standard SQLite table:

    CREATE TABLE BudgetVersions (
        budgetId        VARCHAR  NOT NULL,
        versionName     VARCHAR  NOT NULL,
        dateFormat      VARCHAR,
        currencyFormat  VARCHAR,
        lastAccessedOn  DATETIME,
        isTombstone     BOOL     NOT NULL,
        deviceKnowledge NUMERIC  NOT NULL

    I’ve seen the crash happen on both a KitKat emulator and a device running Lollipop.

    There is a separate writeable connection open to the same database at the same time, owned by a WebView. The database is being updated by Javascript code in the WebView, and read from in the native Android/Java layer with this read-only connection.

    I expect this may prove to be the ultimate cause of the problem, but I’d like to understand in detail why a read-only connection would interfere with a separate writeable connection.

    I am well aware that the general advice is to use a single connection to the database, but since the writeable connection is owned by the WebView, I don’t have easy access to it from the Java code.

    Related posts:

    Android: How to get a radiogroup with togglebuttons?
    How to transition from managedQuery to LoaderManager/CursorLoader?
    listview not updating with notifydatasetchanged() call
    Where is log output written to when using Robolectric + Roboguice?
    System.gc() causing slowdown from the second start of Activity
    Update Navigation drawer listview
  • How to get View object on which animation was started…?
  • Creating a text filter (like quick search) for a Spinner in Android
  • How to correctly filter Package replaced broadcast
  • How to POST data in Android to server in JSON format?
  • Android - Setting TextView to Bold Not Working
  • (Retrofit) Could not locate converter for class crashing app
  • One Solution collect form web for “Attempt to write a readonly database… but I'm not”

    Solved by changing it to a writeable database connection. The clue was in the documentation for the 776 error code:


    The SQLITE_READONLY_ROLLBACK error code is an extended error code for
    that a database cannot be opened because it has a hot journal that
    needs to be rolled back but cannot because the database is readonly.

    During development, I am frequently interrupting the currently-running app to install and run a new version. This causes the currently-running app to be force-stopped by the system. If the Javascript code in the WebView is in the middle of writing to the database via its separate writeable connection when the app is nuked, then a hot journal will be left behind.

    When the new version of the app starts up, the read-only database connection in the native Java code is opened. When this connection spots the journal, it tries to roll back the journal. And because it’s a read-only connection, it fails.

    (This fits with the crash being observed immediately on startup after I’ve made a change.)

    The correct fix is therefore to make the Java connection a writeable connection. This connection never attempts a write during normal operation, but it must write when recovering from a previous interrupted write through the WebView’s writeable connection.

    Android Babe is a Google Android Fan, All about Android Phones, Android Wear, Android Dev and Android Games Apps and so on.