The opt-in encrypted cache (encryptCache) crash-loops on launch for any user who has enabled it, on the first cold start after enabling — reported after an app upgrade on a Pixel 10 Pro XL.
FATAL EXCEPTION: arch_disk_io
java.lang.UnsatisfiedLinkError: No implementation found for long
net.zetetic.database.sqlcipher.SQLiteConnection.nativeOpen(...) — is the library loaded, e.g. System.loadLibrary?
at ...SupportHelper.getWritableDatabase(...) ← Room opening the encrypted cache
Root cause
System.loadLibrary("sqlcipher") (in DatabaseEncryption.ensureNativeLibraryLoaded()) was only ever called as a side effect of an actual plaintext↔encrypted conversion (DatabaseEncryption.migrate) or the one-time #111 account migration (AccountDataMigrator). On a steady-state start the cache is already encrypted (so ensureEncrypted early-returns) and the migration is already done (so it no-ops), so nothing loads the native library before Room opens the keyed DB via SupportOpenHelperFactory → nativeOpen. The previous process survived only because an earlier conversion had loaded the .so in-memory; the next cold start (an upgrade, or any force-stop + relaunch) crashes.
Not a packaging/ABI problem — lib/arm64-v8a/libsqlcipher.so is present in the APK and loads fine; it was simply never asked to load.
Fix
Load the library explicitly in DatabaseProvisioner whenever it commits to an encrypted open (idempotent; no-ops when already loaded), plus regression assertions in DatabaseProvisionerTest (encrypted path must load it; plaintext path must not).
Verified on a Pixel 10 Pro XL: an in-place update preserving the already-encrypted cache now launches to the mailbox instead of crash-looping.
**Status:** Fixed — PR #208 (in review).
## Summary
The opt-in encrypted cache (`encryptCache`) crash-loops on launch for any user who has enabled it, on the first cold start after enabling — reported after an app upgrade on a Pixel 10 Pro XL.
```
FATAL EXCEPTION: arch_disk_io
java.lang.UnsatisfiedLinkError: No implementation found for long
net.zetetic.database.sqlcipher.SQLiteConnection.nativeOpen(...) — is the library loaded, e.g. System.loadLibrary?
at ...SupportHelper.getWritableDatabase(...) ← Room opening the encrypted cache
```
## Root cause
`System.loadLibrary("sqlcipher")` (in `DatabaseEncryption.ensureNativeLibraryLoaded()`) was only ever called as a **side effect** of an actual plaintext↔encrypted conversion (`DatabaseEncryption.migrate`) or the one-time #111 account migration (`AccountDataMigrator`). On a steady-state start the cache is already encrypted (so `ensureEncrypted` early-returns) and the migration is already done (so it no-ops), so nothing loads the native library before Room opens the keyed DB via `SupportOpenHelperFactory` → `nativeOpen`. The previous process survived only because an earlier conversion had loaded the `.so` in-memory; the next cold start (an upgrade, or any force-stop + relaunch) crashes.
Not a packaging/ABI problem — `lib/arm64-v8a/libsqlcipher.so` is present in the APK and loads fine; it was simply never asked to load.
## Fix
Load the library explicitly in `DatabaseProvisioner` whenever it commits to an encrypted open (idempotent; no-ops when already loaded), plus regression assertions in `DatabaseProvisionerTest` (encrypted path must load it; plaintext path must not).
Verified on a Pixel 10 Pro XL: an in-place update preserving the already-encrypted cache now launches to the mailbox instead of crash-looping.
Fix: #208
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Status: Fixed — PR #208 (in review).
Summary
The opt-in encrypted cache (
encryptCache) crash-loops on launch for any user who has enabled it, on the first cold start after enabling — reported after an app upgrade on a Pixel 10 Pro XL.Root cause
System.loadLibrary("sqlcipher")(inDatabaseEncryption.ensureNativeLibraryLoaded()) was only ever called as a side effect of an actual plaintext↔encrypted conversion (DatabaseEncryption.migrate) or the one-time #111 account migration (AccountDataMigrator). On a steady-state start the cache is already encrypted (soensureEncryptedearly-returns) and the migration is already done (so it no-ops), so nothing loads the native library before Room opens the keyed DB viaSupportOpenHelperFactory→nativeOpen. The previous process survived only because an earlier conversion had loaded the.soin-memory; the next cold start (an upgrade, or any force-stop + relaunch) crashes.Not a packaging/ABI problem —
lib/arm64-v8a/libsqlcipher.sois present in the APK and loads fine; it was simply never asked to load.Fix
Load the library explicitly in
DatabaseProvisionerwhenever it commits to an encrypted open (idempotent; no-ops when already loaded), plus regression assertions inDatabaseProvisionerTest(encrypted path must load it; plaintext path must not).Verified on a Pixel 10 Pro XL: an in-place update preserving the already-encrypted cache now launches to the mailbox instead of crash-looping.
Fix: #208