{"record":{"id":"5adef021f34580f2","repo":"MuntashirAkon/AppManager","slug":"master-key-exists-but-it-didn-t-exist-when-the-backup-was","errorCode":null,"errorMessage":"Master key exists but it didn't exist when the backup was made.","messagePattern":"Master key exists but it didn't exist when the backup was made\\.","errorType":"exception","errorClass":"BackupException","httpStatus":null,"severity":"error","filePath":"app/src/main/java/io/github/muntashirakon/AppManager/backup/RestoreOp.java","lineNumber":266,"sourceCode":"        }\n    }\n\n    private void checkMasterKey() throws BackupException {\n        if (true) {\n            // TODO: 6/2/22 MasterKey may not actually be necessary.\n            return;\n        }\n        String oldChecksum = mChecksum.get(MASTER_KEY);\n        Path masterKey;\n        try {\n            masterKey = KeyStoreUtils.getMasterKey(mUserId);\n        } catch (FileNotFoundException e) {\n            if (oldChecksum == null) return;\n            else\n                throw new BackupException(\"Master key existed when the checksum was made but now it doesn't.\");\n        }\n        if (oldChecksum == null) {\n            throw new BackupException(\"Master key exists but it didn't exist when the backup was made.\");\n        }\n        String newChecksum = DigestUtils.getHexDigest(mBackupInfo.checksumAlgo, masterKey.getContentAsString().getBytes());\n        if (!newChecksum.equals(oldChecksum)) {\n            throw new BackupException(\"Checksums for master key did not match.\");\n        }\n    }\n\n    private void restoreApkFiles() throws BackupException {\n        if (!mBackupFlags.backupApkFiles()) {\n            throw new BackupException(\"APK restore is requested but backup doesn't contain any source files.\");\n        }\n        Path[] backupSourceFiles = mBackupItem.getSourceFiles();\n        if (backupSourceFiles.length == 0) {\n            // No source backup found\n            throw new BackupException(\"Source restore is requested but there are no source files.\");\n        }\n        boolean isVerified = true;\n        if (mPackageInfo != null) {","sourceCodeStart":248,"sourceCodeEnd":284,"githubUrl":"https://github.com/MuntashirAkon/AppManager/blob/0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5/app/src/main/java/io/github/muntashirakon/AppManager/backup/RestoreOp.java#L248-L284","documentation":"checkMasterKey() throws this when a keystore master key currently exists but the backup's checksum file has no checksum entry for the master key (mChecksum.get(MASTER_KEY) == null). This means the key was provisioned after the backup was taken, so the backup's encrypted data was not made with (or verified against) the current key. Like error 111, it is currently unreachable due to the early return in checkMasterKey().","triggerScenarios":"KeyStoreUtils.getMasterKey(mUserId) succeeds, but oldChecksum = mChecksum.get(MASTER_KEY) is null during a restore.","commonSituations":"Backups taken before App Manager ever created a master key are restored on a device where the key now exists (e.g. after an earlier backup created it); mixing backup sets from an older App Manager version with a newer install; copying checksum files from one backup to another.","solutions":["Restore the matching checksum file that accompanied the original backup; do not mix checksum files across backup sets.","If the backup predates master-key usage, upgrade App Manager to a build where checkMasterKey is skipped (early return) or restore with a version contemporary to the backup.","If decryption is needed and the key is wrong, re-create the backup on the device/profile holding the correct key.","Confirm the backup directory contains all companion files (checksums, metadata) — a partial copy can lose the MASTER_KEY checksum entry."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Ensure the checksum set matches key state before restoring:\nboolean keyExists = true;\ntry { KeyStoreUtils.getMasterKey(userId); } catch (FileNotFoundException e) { keyExists = false; }\nif (keyExists && checksums.get(MASTER_KEY) == null) {\n    // backup predates key: use matching tooling/backup set\n}","typeGuard":null,"tryCatchPattern":"try { restoreOp.runRestore(); } catch (BackupException e) {\n    if (e.getMessage().contains(\"Master key exists but it didn't exist when the backup was made\")) {\n        // use App Manager version contemporary with the backup, or restore without key verification\n    }\n}","preventionTips":["Keep complete backup sets (metadata + checksums) together; never mix files across backups.","Restore with an App Manager version from the same era as the backup.","Document when master keys were provisioned on the device."],"tags":["android","keystore","backup","encryption"],"backgroundTag":"invalid-state-transition","analyzedSha":"0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5","analyzedAt":"2026-09-12T14:03:37.243Z","contentChangedAt":"2026-09-12T14:03:37.243Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}