This article covers common failure modes and troubleshooting strategies for Automatic Account Recovery (AAR) (also known as Account Migration) when users switch devices or reinstall your application. (add a link to the original KB AAR article)
Core Requirements for AAR
Before troubleshooting specific errors, ensure these baseline conditions are met:
- Feature: AAR must be enabled in the Admin Dashboard under Settings > Features. (If disabled, contact support@futurae.com)
- Fresh Installation: The app on the new (target) device must be a fresh install with no other accounts enrolled. The automatic recovery process will not run if it detects an account on the device.
-
System Backups:
- iOS: iCloud Keychain must be enabled on both the source and target devices. If migrating via a physical computer, the iTunes backup must be encrypted.
- Android: The app must implement a BackupAgent to include the Futurae SDK's data in the Android Backup service.
The End-to-End AAR Lifecycle
The Automatic Account Recovery lifecycle generally follows four phases:
| # | Phase | What happens |
|---|---|---|
| 1 | Enrollment | The user successfully enrolls an account on the original device. |
| 2 | Cloud Sync | The native OS automatically backs up the encrypted SDK recovery payload to the user's cloud account. |
| 3 | Restore | The user sets up a new target device and performs an OS-level restore from their cloud backup. |
| 4 | Migration | Upon launching the newly restored app, the Futurae SDK detects the backup payload and completes the account migration. |
iOS Troubleshooting
On iOS, the Futurae SDK maintains two distinct copies of migration data to handle both same-device reinstalls and cross-device restores:
-
Cross-Device Restore (Cloud/Backup): An encrypted migration payload file stored in the app container (included in system backups), secured by an AES encryption key saved in the Keychain with
kSecAttrSynchronizable=true. -
Same-Device Reinstall: A local copy stored directly in the Keychain set to
ThisDeviceOnly(kSecAttrSynchronizable=false), which persists across app reinstallations on the same physical device without relying on cloud sync.
Platform Prerequisites
- iCloud Keychain: Must be explicitly turned ON in iOS Settings on both source and target devices.
- iTunes Backup Encryption: If backing up via a physical computer (macOS/PC), the iTunes backup must be encrypted for Keychain items to persist.
- SDK Version: Requires iOS SDK v3.x.x or higher to ensure cryptographic key persistence during iCloud restore cycles.
iOS Error Reference (SDKMigrationErrorCode)
When a migration fails on iOS, the SDKMigrationError object provides an sdkCode property mapped to SDKMigrationErrorCode.
migrationInfoMissing
CauseNo valid migration payload was found in the restored device backup. If you encounter this behavior, verify the following platform environmental causes:
- iCloud Keychain Disabled: The iOS SDK uses a special encryption key that syncs across the user's Apple devices via iCloud (using the kSecAttrSynchronizable attribute). If the user has disabled iCloud Keychain in iOS settings, this key will not transfer to a new device, even if the app's files are restored. For the transfer to succeed, iCloud Keychain must be explicitly enabled in iOS Settings on both the source (old) and target (new) devices.
- iCloud Keychain Sync Delay: The app's backup file and the iCloud Keychain encryption key restore independently on separate schedules. The Keychain key can lag by several minutes and requires the target device to be unlocked and connected to the internet. Attempting migration in this brief window will trigger migrationInfoMissing even if the backup itself is valid.
- Stale or Outdated Backup: The restored system backup must have been created after the Futurae account was enrolled. Restoring from a backup that predates account enrollment will result in missing payload files.
- AAR Disabled at Enrollment Time: Migration payloads are generated only at account enrollment (users enrolled before enabling AAR must re-enroll to become recoverable).
- Manual Keychain Deletion: If your app logic clears the Keychain (e.g., during first launch), ensure your code does not delete keys where kSecAttrSynchronizable is true.
accountsExistError
CauseActive accounts are already enrolled on the target device.
ResolutionAAR requires a clean target environment. Reset or reinstall the app.
accountPreviouslyEnrolledError
CauseAn account was previously enrolled on the device, which conflicts with the migration process.
ResolutionFully reset all historical SDK states using the SDK reset method before attempting recovery.
*For a complete list of all enumeration cases (including noDeviceUDID and noMigrationToken), please refer to the official Futurae iOS SDK Documentation.
Testing on iOS
⚠️ Simulator Limitation
iOS Simulators do not replicate full iCloud Keychain sync behaviors. Deleting and reinstalling an app on a simulator will not clear local Keychain items.
- Physical Device Testing (Recommended): Use two physical test devices signed into the same Apple ID with iCloud Keychain active.
- Simulated Local Wipe (Single Device): To clear historical SDK data and prepare a device for testing without corrupting synchronized keys, do not attempt manual Keychain deletion snippets (SecItemDelete). Deleting specific key classes alone leaves generic-password items (like device tokens and UDIDs) behind, which causes the SDK to throw an accountPreviouslyEnrolledError. Instead, invoke the SDK reset method to cleanly wipe local SDK state
Android Troubleshooting
Android migration relies on the native Android Backup Service. The Futurae SDK stores encrypted migration data inside the app container, which is backed up using the device's encrypted cloud backup
Platform Prerequisites
-
Manifest Configuration: Ensure
android:allowBackup="true"is set in<application>and your customBackupAgentis correctly registered. - Cloud Backup Active: The user must have Cloud Backup enabled under Android System Settings (e.g., Google One, Samsung Cloud, etc.).
🚨 Limitation
The Futurae SDK relies strictly on native Android Native Cloud Backup Services. If a user backs up via Samsung Cloud and restores to another device with a different cloud provider, the Futurae recovery payload will be missing.
Android Error Reference (FTAccountsMigrationException)
FTAccountMigrationNoMigrationInfoException
CauseNo valid recovery data was found in the restored app container.
Checklist
-
Missing BackupAgent: Your app manifest lacks a properly configured
BackupAgent. - Backup Pending: Android OS has not yet performed a cloud backup cycle (backups typically occur only when the device is idle, charging, or on Wi-Fi). A valid backup must be available during the app's installation.
-
SDK Reset executed before backup: Calling
FuturaeSDK.client.reset()locally deletes the local migration payload. If done before the OS backs up, the account cannot be recovered.
FTAccountsMigrationAccountsExistException
CauseActive accounts are present on the device.
ResolutionThe app has to be reinstalled.
FTApiAuthorizationFailedException (401 Unauthorized)
Cause
-
Stale Migration Tokens: Upon enrollment/recovery, the backend issues a single-use
migration_token. If an Android device restores from an outdated backup created before the latest server sync, the SDK presents an already consumed token, triggering a 401 error. -
MigratableAccounts requirements: The SDK's
FuturaeMigrationAPI.getMigratableAccountsindicates if themigrateAccountsAPI will require PIN or Adaptive migration. If these requirements are not fulfilled, then the migration will fail with this error.
PreventionAlways perform FuturaeMigrationAPI.getMigratableAccounts to check if a migration is available and its requirements. This operation does NOT consume the migration token.
Testing on Android
You do not need to wait for automatic OS backup schedules during testing. Use the Android Debug Bridge (ADB) to force immediate backup and restore cycles. For reference: https://developer.android.com/tools/adb, (specifically: https://developer.android.com/tools/bmgr)
1. Force a Backup (Source Device)
After you have enrolled an account and ensured your BackupAgent is implemented, run these commands to push the data to the cloud:
# Initialize and enable the backup manager
adb shell bmgr run
adb shell bmgr enabled
# Force an immediate backup for your app package
adb shell bmgr backupnow <your.package.name>
2. Force a Restore (Target/New Device)
To test the recovery flow without physically switching phones, you can uninstall and reinstall the app, then force a restore:
# List available backup sets to locate your <token>
adb shell bmgr list sets
# Force restore the backup payload to your app
adb shell bmgr restore <token> <your.package.name>
Cross-Device Android Testing Note
Ensure your test builds use identical or higher version codes on the target device. By default, android:restoreAnyVersion is set toFalse, preventing Android from restoring backups generated by newer app versions onto older builds.
Ecosystem Limitation: Google Backup vs. Manufacturer Backups (e.g., Samsung Cloud)
A common point of confusion during both testing and production support is how different Android device manufacturers handle system backups.
- The Dependency: The Futurae Automatic Account Recovery solution relies strictly on the native Cloud Android Backup Service (Google Drive / Google Cloud).
- The Problem: Many Android device manufacturers implement their own parallel cloud ecosystems. For example, Samsung devices default to Samsung Cloud / Smart Switch backup systems, while other vendors utilize alternative proprietary cloud environments.
- The Reality: Proprietary manufacturer clouds (like Samsung Cloud) may not route data through the standard Android Backup Manager APIs. If an end-user backs up their old device using Samsung Cloud and attempts to restore it on a new device (especially a non-Samsung device like a Google Pixel), cross-cloud restoration will fail, and the Futurae recovery payload will be completely missing.
📘 Support Tip
When troubleshooting missing migration data (FTAccountMigrationNoMigrationInfoException) for end-users on OEM devices like Samsung, verify whether they used a standard Google Account Cloud backup or the manufacturer's proprietary cloud account during their device setup wizard. Account recovery will only succeed if the standard Google Backup framework was utilized.
Trusted Binding Issues
If your Futurae implementation utilizes Trusted Binding and the migration stalls or fails on Android without a clear local exception, ensure that your application backend is successfully generating and providing a valid binding token to the client app during the recovery handshake.
Error Code Quick Reference (iOS/Android)
| Android Error | iOS Error | Description | Primary Resolution |
|---|---|---|---|
FTAccountMigrationNoMigrationInfoException |
SDKMigrationErrorCode.migrationInfoMissing |
No backup data found. | Verify iCloud Keychain (iOS) or BackupAgent (Android). |
FTAccountsMigrationAccountsExistException |
SDKMigrationErrorCode.accountsExistError |
SDK already has accounts | Reset the SDK before migrating. |
FTAccountsMigrationAccountsPreviouslyEnrolledException |
SDKMigrationErrorCode.accountPreviouslyEnrolledError |
An account is already enrolled on this device. | Ensure a clean install with no historical SDK data. |
Advanced Testing & OS Edge Cases
Testing Automatic Account Recovery can be challenging because it relies on native OS backup managers, which operate asynchronously. Below are the specific commands and methods to force these processes for testing.
Android: Cross-Device Hardware Constraints
When simulating a two-device account migration environment, several native Android OS constraints outside of the Futurae SDK's control can prevent the onRestore() lifecycle method from executing successfully:
- Version Matching (android:restoreAnyVersion): By default, the android:restoreAnyVersion manifest attribute is set to false. This explicitly prevents Android from restoring backup archives that were originally generated by a newer version code of your application onto an older version installation. Ensure your test build version numbers match or surpass the backup source version.
- Per-Device Backup Sets: Google Backup Services partitions backup data pools per device hardware signature. The native OS cloud coordinator dynamically establishes which backup set to prioritize based on device synchronization logs, idle times, and payload metadata, meaning a target device may not immediately pull down data generated by a separate source testing device.
- Cloud Transport Fragmentation: Backup restoration pathways are strictly bound to the device manufacturer's cloud transport ecosystem. For example, Google Pixel hardware utilizes Google Cloud transport pools, whereas Samsung devices frequently prioritize Samsung Cloud architectures. Cross-cloud restore cycles between contrasting vendor infrastructures are fundamentally unsupported by the underlying Android operating system.
iOS: Simulating the Recovery Environment
Because true iCloud syncing requires two separate physical iPhones signed into the same Apple ID, you can simulate a restore lifecycle on a single device or simulator:
The "Simulated Migration" Flow
To test how your app handles the FTRAccountMigrationErrorNoMigrationInfo error or successful decryption:
- Enroll an account in your app.
- Uninstall the app (this simulates a "fresh" state) and reinstall.
- The "iCloud" Simulation (Optional): If you want to simulate a new device where local (non-sync) keys are missing, use the SDK reset method: 'FTRClient.reset(...)' to delete only non-synchronizable items before the SDK initializes.
- Initialize SDK: Call getMigratableAccounts. If the sync-keys (version 2.6.5+) are present, migration should be possible.
Best Practices & Troubleshooting Checklist for Developers
- Verify User Presence: If the SDK is configured with lock configuration type BIOMETRICS_ONLY, BIOMETRICS_OR_DEVICE_CREDENTIALS, or SDK_PIN_WITH_BIOMETRICS_OPTIONAL, always verify user presence (FaceID/TouchID/SDK PIN) before calling migrateAccounts.
-
Two-Layered App Data (iOS): If you need to migrate your own app-specific data alongside Futurae accounts:
- For Backups: Store a file in the app container and encrypt it with a kSecAttrSynchronizable = true key.
- For Reinstalls: Store data directly in the Keychain with default settings.
Useful references:
Secure keychain syncing: https://support.apple.com/guide/security/secure-keychain-syncing-sec0a319b35f/web
| Step | Action | Why? |
|---|---|---|
| 1 | Check Admin Portal | AAR must be "ON" for the specific Service ID. |
| 2 | Check pinProtected | If true, you must pass the old SDK PIN to migrateAccounts. |
| 3 | Check Device Lock | If using BIOMETRICS_ONLY or BIOMETRICS_OR_DEVICE_CREDENTIALS, a prior unlock is required before calling the migration method. |
| 4 | Check SDK Version | iOS: Must be SDK v3.x.x for reliable iCloud syncing. Android: Must be SDK v3.x.x (***) |
Need help? For any technical support, do not hesitate to contact our team support@futurae.com.
Comments
0 comments
Article is closed for comments.