MuntashirAkon/AppManager · error · BackupException

Could not get crypto

Error message

Could not get crypto 

What it means

After availability checks pass, RestoreOp calls mBackupItem.setCrypto(mBackupInfo.getCrypto()); a CryptoException is wrapped as BackupException 'Could not get crypto <mode>'. Unlike error 100 this happens on the restore path and the backup item is cleaned up before aborting.

Source

Thrown at app/src/main/java/io/github/muntashirakon/AppManager/backup/RestoreOp.java:128

        mBackupItem = backupItem;
        mUserId = userId;
        try {
            mBackupInfo = mBackupItem.getInfo();
            mBackupFlags = mBackupInfo.flags;
        } catch (IOException e) {
            mBackupItem.cleanup();
            throw new BackupException("Could not read backup info. Possibly due to a malformed json file.", e);
        }
        // Setup crypto
        if (!CryptoUtils.isAvailable(mBackupInfo.crypto)) {
            mBackupItem.cleanup();
            throw new BackupException("Mode " + mBackupInfo.crypto + " is currently unavailable.");
        }
        try {
            mBackupItem.setCrypto(mBackupInfo.getCrypto());
        } catch (CryptoException e) {
            mBackupItem.cleanup();
            throw new BackupException("Could not get crypto " + mBackupInfo.crypto, e);
        }
        try {
            mBackupMetadata = mBackupItem.getMetadata(mBackupInfo).metadata;
        } catch (IOException e) {
            mBackupItem.cleanup();
            throw new BackupException("Could not read backup metadata. Possibly due to a malformed json file.", e);
        }
        // Get checksums
        try {
            mChecksum = mBackupItem.getChecksum();
        } catch (Throwable e) {
            mBackupItem.cleanup();
            throw new BackupException("Failed to get checksums.", e);
        }
        // Verify metadata
        if (!requestedFlags.skipSignatureCheck()) {
            try {
                verifyMetadata();

View on GitHub (pinned to 0152f468fc)

Solutions

  1. Supply the correct password/key used when the backup was created
  2. Ensure all crypto key files/directories belonging to the backup were copied together with the backup
  3. Inspect the wrapped CryptoException cause to distinguish wrong-key from missing-backend problems
  4. Re-create the backup with a working crypto mode if key material is unrecoverable

Example fix

// before
try {
    mBackupItem.setCrypto(mBackupInfo.getCrypto());
} catch (CryptoException e) {
    mBackupItem.cleanup();
    throw new BackupException("Could not get crypto " + mBackupInfo.crypto, e);
}
// after
try {
    mBackupItem.setCrypto(mBackupInfo.getCrypto());
} catch (CryptoException e) {
    mBackupItem.cleanup();
    throw new BackupException("Could not get crypto " + mBackupInfo.crypto
            + ": check password/key availability (cause: " + e.getMessage() + ")", e);
}
Defensive patterns

Strategy: try-catch

Validate before calling

// after isAvailable passes, verify key material exists for the mode before setCrypto
if (!CryptoUtils.hasKeyMaterial(backupDir, mode)) throw new BackupException("Key/password for mode " + mode + " not available");

Try / catch

try { new RestoreOp(...); } catch (BackupException e) { if (e.getMessage().startsWith("Could not get crypto")) { promptForPassword(); } throw e; }

Prevention

When it happens

Trigger: setCrypto initialization fails despite isAvailable passing: wrong password/key derivation failure, corrupted key files, or the crypto backend throwing during setup for the encrypted backup.

Common situations: User restored a backup without its paired key/password; encrypted backup transferred without the hidden key directory; ROM update changed key storage semantics.

Related errors


AI-assisted analysis of MuntashirAkon/AppManager@0152f468fc (2026-09-12). Data as JSON: /api/errors/284eae9ca9d59303. Report an issue: GitHub.