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

  1. Re-enter the correct backup password carefully (check keyboard layout, trailing spaces)
  2. Try common password variants used when the backup was created
  3. If the header may be corrupted, verify the salt/round lines against a known-good backup header
  4. 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

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


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)