Guidelines
Bug description
I've been trying to move my Signal account from an iPhone 11 to a Pixel 9 using the Signal Secure Backups paid tier. Restoring the exact same backup between iPhones works fine now, but a few months ago did not. Restoring it on Android fails every time I've tried, on both GrapheneOS and stock Pixel OS (and once in Waydroid for fun), with the current stable release (the APK from signal.org, not Google Play) and the newest pre-release from GitHub.
The restore downloads the archive, restores ~800k messages, and then fails during the "finishing" step. On the stable release this failure is completely silent -- the dialog just closes and it goes back to the "restore from a cloud backup" screen with no error. The logcat shows that the import completes, then a final integrity check throws an uncaught IllegalStateException for foreign key violations on message.latest_revision_id, and the process gets killed.
There are only a few violations out of ~800k messages. I am unsure what causes them -- Claude told me it was possibly 3 edited messages whose revision references the iOS exporter writes in a way the Android importer can't resolve -- but I haven't looked into it enough to know.
Recreating the backup from scratch on the iPhone (turn off and delete backup, re-enable, fresh backup) does not help -- the new archive fails identically, so this reproduces from the iOS exporter side, not from one stale archive.
Steps to reproduce
- On iOS (latest App Store version), enable Signal Secure Backups (paid tier) and let a backup complete
- On a Pixel 9 (GrapheneOS or stock, doesn't matter), install Signal, fresh install
- During registration, choose Transfer or restore account -> From Signal Backups, enter the recovery key (or scan the QR code and choose restore from backup, the same thing happened to me for both)
- Wait for the restore to download and process all messages
Actual result
Stable (APK from signal.org): after the message import finishes, the "finishing" dialog closes and the app silently returns to the restore-from-cloud-backup screen. logcat shows an uncaught exception and the process being killed:
07-16 14:05:15.209 E SignalUncaughtException: java.lang.IllegalStateException: Foreign key check failed! Violations: [ForeignKeyViolation(table=message, violatingRowId=392184, dependsOnTable=message, column=latest_revision_id), ForeignKeyViolation(table=message, violatingRowId=392188, dependsOnTable=message, column=latest_revision_id), ForeignKeyViolation(table=message, violatingRowId=778878, dependsOnTable=message, column=latest_revision_id), ForeignKeyViolation(table=message, violatingRowId=778881, dependsOnTable=message, column=latest_revision_id), ForeignKeyViolation(table=message, violatingRowId=802186, dependsOnTable=message, column=latest_revision_id), ForeignKeyViolation(table=message, violatingRowId=802190, dependsOnTable=message, column=latest_revision_id)]
07-16 14:05:15.209 E SignalUncaughtException: at org.thoughtcrime.securesms.backup.v2.BackupRepository.import(BackupRepository.kt:1447)
07-16 14:05:15.209 E SignalUncaughtException: at org.thoughtcrime.securesms.backup.v2.BackupRepository.importSignalBackup(BackupRepository.kt:1160)
07-16 14:05:15.209 E SignalUncaughtException: at org.thoughtcrime.securesms.backup.v2.BackupRepository.restoreRemoteBackup(BackupRepository.kt:2306)
07-16 14:05:15.209 E SignalUncaughtException: at org.thoughtcrime.securesms.backup.v2.BackupRepository.access$restoreRemoteBackup(BackupRepository.kt:188)
07-16 14:05:15.209 E SignalUncaughtException: at org.thoughtcrime.securesms.backup.v2.BackupRepository$restoreRemoteBackup$2.invokeSuspend(BackupRepository.kt:2210)
07-16 14:05:15.209 E SignalUncaughtException: at org.signal.registration.ui.restore.RemoteRestoreViewModel$restore$1$2.invokeSuspend(RemoteRestoreViewModel.kt:120)
07-16 14:05:15.224 I Process : Sending signal. PID: 19457 SIG: 9
07-16 14:05:15.302 I Zygote : Process 19457 exited due to signal 9 (Killed)
While the import is running there are also repeated warnings like this, if it's relevant:
07-16 14:00:02.370 W SQLiteConnectionPool: The connection pool for database '/data/user/0/org.thoughtcrime.securesms/databases/signal.db' has been unable to grant a connection to thread 116 (JobRunner-Core-3) with flags 0x2 for 30.000002 seconds.
Newest pre-release from GitHub: same backup, same failure at the same point (around 7 minutes in, right after the message import), but the error is now caught and an error dialog is shown instead of the process crashing. The failure surfaces from RemoteBackupRestoreView / BackupRepository.importSignalBackup(BackupRepository.kt:1162). So the silent-failure part got fixed at some point, but the restore still fails.
Expected result
The restore completes. Ideally the importer would repair or drop the ~6 orphaned latest_revision_id references (or the iOS exporter wouldn't emit them) rather than discarding an entire 800k-message restore over them. iOS -> Android restores are documented as supported, so this backup should be importable.
Screenshots
No response
Device
Pixel 9 and iPhone 11
Android version
17 (Stock OS & GrapheneOS -- attached logs are from stock)
Signal version
8.19.2
Link to debug log
Full logcat captures from both builds are attached (stable-apk-logcat.txt and prerelease-apk-logcat.txt). Lines containing my home Wi-Fi network's SSID/BSSID/IP have been removed for privacy; nothing Signal-related was removed. Let me know if there's any other logs I should provide too.
stable-apk-logcat.txt
prerelease-apk-logcat.txt
Guidelines
Bug description
I've been trying to move my Signal account from an iPhone 11 to a Pixel 9 using the Signal Secure Backups paid tier. Restoring the exact same backup between iPhones works fine now, but a few months ago did not. Restoring it on Android fails every time I've tried, on both GrapheneOS and stock Pixel OS (and once in Waydroid for fun), with the current stable release (the APK from signal.org, not Google Play) and the newest pre-release from GitHub.
The restore downloads the archive, restores ~800k messages, and then fails during the "finishing" step. On the stable release this failure is completely silent -- the dialog just closes and it goes back to the "restore from a cloud backup" screen with no error. The logcat shows that the import completes, then a final integrity check throws an uncaught
IllegalStateExceptionfor foreign key violations onmessage.latest_revision_id, and the process gets killed.There are only a few violations out of ~800k messages. I am unsure what causes them -- Claude told me it was possibly 3 edited messages whose revision references the iOS exporter writes in a way the Android importer can't resolve -- but I haven't looked into it enough to know.
Recreating the backup from scratch on the iPhone (turn off and delete backup, re-enable, fresh backup) does not help -- the new archive fails identically, so this reproduces from the iOS exporter side, not from one stale archive.
Steps to reproduce
Actual result
Stable (APK from signal.org): after the message import finishes, the "finishing" dialog closes and the app silently returns to the restore-from-cloud-backup screen. logcat shows an uncaught exception and the process being killed:
While the import is running there are also repeated warnings like this, if it's relevant:
Newest pre-release from GitHub: same backup, same failure at the same point (around 7 minutes in, right after the message import), but the error is now caught and an error dialog is shown instead of the process crashing. The failure surfaces from
RemoteBackupRestoreView/BackupRepository.importSignalBackup(BackupRepository.kt:1162). So the silent-failure part got fixed at some point, but the restore still fails.Expected result
The restore completes. Ideally the importer would repair or drop the ~6 orphaned
latest_revision_idreferences (or the iOS exporter wouldn't emit them) rather than discarding an entire 800k-message restore over them. iOS -> Android restores are documented as supported, so this backup should be importable.Screenshots
No response
Device
Pixel 9 and iPhone 11
Android version
17 (Stock OS & GrapheneOS -- attached logs are from stock)
Signal version
8.19.2
Link to debug log
Full logcat captures from both builds are attached (
stable-apk-logcat.txtandprerelease-apk-logcat.txt). Lines containing my home Wi-Fi network's SSID/BSSID/IP have been removed for privacy; nothing Signal-related was removed. Let me know if there's any other logs I should provide too.stable-apk-logcat.txt
prerelease-apk-logcat.txt