MuntashirAkon/AppManager · error · IOException
Incorrect password
Error message
Incorrect password
What it means
IOException from AndroidBackupHeader.attemptEncryptionKeyDecryption: the PBKDF2-derived key failed the PBKDF2 verification check built into the Android backup format, meaning the supplied password (combined with the stored user/checksum salts and rounds) does not derive the correct key.
Solutions
- Re-enter the correct backup password carefully (check keyboard layout, trailing spaces)
- Try common password variants used when the backup was created
- If the header may be corrupted, verify the salt/round lines against a known-good backup header
- Without the correct password the backup is cryptographically unrecoverable — create a new backup
Example fix
// before
new AndroidBackupHeader(stream, "password123".toCharArray()).toTar(); // guess
// after
char[] pw = System.console().readPassword("Backup password: ");
if (pw == null || pw.length == 0) throw new IllegalArgumentException("Password required");
new AndroidBackupHeader(stream, pw).toTar(); Defensive patterns
Strategy: try-catch
Validate before calling
// No pre-check can validate a password; enforce non-empty and prompt deliberately
if (password == null || password.length == 0) {
throw new IllegalArgumentException("Encrypted backup requires a password");
} Try / catch
try {
InputStream tar = header.toTar();
} catch (IOException e) {
if (e.getMessage().contains("Incorrect password")) {
char[] pw = System.console().readPassword("Wrong password. Try again: ");
header = new AndroidBackupHeader(reopen(stream), pw);
tar = header.toTar();
} else throw e;
} Prevention
- Re-read the password from the user rather than retrying stored guesses
- Beware keyboard layouts and autocomplete when the backup was created
- Store backup passwords in a credential manager, not scripts
- Accept that wrong-password backups are unrecoverable; keep the raw stream for retries
When it happens
Trigger: A wrong or mistyped password was supplied to an encrypted .ab backup; also triggered when salt/iteration lines in the header are corrupted so verification fails even with the right password.
Common situations: Users forgetting the password typed at 'adb backup' time; keyboard layout/input-method differences; automated scripts with placeholder passwords; header corruption from partial transfers.
Related errors
- Archive is encrypted but no password given
- Checksums for master key did not match.
- Couldn't delete old file
- Couldn't get misc.am.tsv for generating checksum
- Failed to decrypt
AI-assisted analysis of MuntashirAkon/AppManager@0152f468fc (2026-09-12).
Data as JSON: /api/errors/53fb58eda418401d.
Report an issue: GitHub.
Appendix: source
Thrown at app/src/main/java/io/github/muntashirakon/AppManager/backup/adb/AndroidBackupHeader.java:307
offset, offset + len);
offset += len;
// and finally the encryption key checksum hash
len = mkBlob[offset++];
byte[] mkChecksum = Arrays.copyOfRange(mkBlob,
offset, offset + len);
// now validate the decrypted encryption key against the checksum
byte[] calculatedCk = makeKeyChecksum(algorithm, encryptionKey, ckSalt,
rounds);
if (MessageDigest.isEqual(calculatedCk, mkChecksum)) {
ivSpec = new IvParameterSpec(IV);
c.init(Cipher.DECRYPT_MODE,
new SecretKeySpec(encryptionKey, "AES"),
ivSpec);
// Only if all of the above worked properly will 'result' be assigned
result = new CipherInputStream(rawInStream, c);
} else {
throw new IOException("Incorrect password");
}
return result;
}
/**
* Used for generating random salts or passwords.
*/
public byte[] randomBytes(int bits) {
byte[] array = new byte[bits / 8];
mRng.nextBytes(array);
return array;
}
@NonNull
private static String readHeaderLine(@NonNull InputStream in) throws IOException {
int c;
StringBuilder buffer = new StringBuilder(80);View on GitHub (pinned to 0152f468fc)