MuntashirAkon/AppManager · error · IOException
Failed to get crypto
Error message
Failed to get crypto
What it means
MetadataManager.setCrypto wraps CryptoException from BackupItem.setCrypto into an IOException with the failing crypto mode name appended. It is thrown when the crypto engine accepted the mode as 'available' but actually instantiating/initializing it for the backup item fails. This blocks reading the backup metadata during a restore.
Source
Thrown at app/src/main/java/io/github/muntashirakon/AppManager/backup/MetadataManager.java:167
Path infoFile = backupFile.getInfoFile();
try (OutputStream outputStream = infoFile.openOutputStream()) {
outputStream.write(metadata.info.serializeToJson().toString(4).getBytes());
filenameChecksumMap.put(infoFile.getName(), DigestUtils.getHexDigest(
metadata.info.checksumAlgo, infoFile));
} catch (JSONException e) {
throw new IOException(e.getMessage() + " for file " + infoFile, e);
}
return filenameChecksumMap;
}
private static void setCrypto(@NonNull BackupItems.BackupItem backupItem, @NonNull BackupMetadataV5.Info backupInfo) throws IOException {
if (!CryptoUtils.isAvailable(backupInfo.crypto)) {
throw new IOException("Mode " + backupInfo.crypto + " is currently unavailable.");
}
try {
backupItem.setCrypto(backupInfo.getCrypto());
} catch (CryptoException e) {
throw new IOException("Failed to get crypto " + backupInfo.crypto, e);
}
}
}
View on GitHub (pinned to 0152f468fc)
Solutions
- Verify the crypto mode recorded in backup.json is actually usable on this device (CryptoUtils.isAvailable passes but initialization fails — check the wrapped CryptoException cause)
- Re-enter the correct password/key for the mode (most CryptoException cases stem from key derivation failure)
- Move to a device/ROM that supports the mode (e.g. ecryptfs-enabled ROM) or re-create the backup with a supported mode
- If the cause is missing key files, restore the crypto key material before retrying the restore
Example fix
// before
backupItem.setCrypto(backupInfo.getCrypto());
// after
if (CryptoUtils.isAvailable(backupInfo.crypto)) {
try {
backupItem.setCrypto(backupInfo.getCrypto());
} catch (CryptoException e) {
Log.e(TAG, "Crypto init failed for mode " + backupInfo.crypto, e);
throw new IOException("Failed to get crypto " + backupInfo.crypto, e);
}
} Defensive patterns
Strategy: try-catch
Validate before calling
if (!CryptoUtils.isAvailable(mode)) throw new IOException("Mode " + mode + " unavailable before metadata read"); Type guard
boolean cryptoUsable(String mode) { return CryptoUtils.isAvailable(mode); } Try / catch
try { readMetadata(...); } catch (IOException e) { if (e.getMessage() != null && e.getMessage().startsWith("Failed to get crypto")) { promptForPasswordOrAbort(); } else throw e; } Prevention
- Always check CryptoUtils.isAvailable before attempting a restore
- Keep backup passwords/keys stored alongside backup records
- Test-restore on the target device/ROM before deleting the source backup
When it happens
Trigger: readMetadata -> setCrypto calls backupItem.setCrypto(backupInfo.getCrypto()) and CryptoUtils throws CryptoException, e.g. key/password mismatch, missing crypto provider files (MasterCrypt/ECryptfs unavailable), or a corrupted encrypted header.
Common situations: Restoring a backup made with a password/keystore the user no longer has; Android version changed so the chosen crypto mode's kernel module (ecryptfs) is gone; backup json lists a mode whose key files were not restored.
Related errors
- Could not get crypto
- Android System (android) cannot be restored.
- Restore is requested without any flags.
- No base backup found.
- Could not get backup files.
AI-assisted analysis of MuntashirAkon/AppManager@0152f468fc (2026-09-12).
Data as JSON: /api/errors/61b35a2f42f910c1.
Report an issue: GitHub.