{"record":{"id":"fb8d05e7e773cc80","repo":"MuntashirAkon/AppManager","slug":"apk-restore-is-requested-but-backup-doesn-t-contain-any","errorCode":null,"errorMessage":"APK restore is requested but backup doesn't contain any source files.","messagePattern":"APK restore is requested but backup doesn't contain any source files\\.","errorType":"exception","errorClass":"BackupException","httpStatus":null,"severity":"error","filePath":"app/src/main/java/io/github/muntashirakon/AppManager/backup/RestoreOp.java","lineNumber":276,"sourceCode":"        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) {\n            // Check signature of the installed app\n            List<String> certChecksumList = Arrays.asList(PackageUtils.getSigningCertChecksums(mBackupInfo.checksumAlgo, mPackageInfo, false));\n            String[] certChecksums = BackupItems.Checksum.getCertChecksums(mChecksum);\n            for (String checksum : certChecksums) {\n                if (certChecksumList.contains(checksum)) continue;\n                isVerified = false;\n                if (!mRequestedFlags.skipSignatureCheck()) {\n                    throw new BackupException(\"Signing info verification failed.\" +\n                            \"\\nInstalled: \" + certChecksumList +\n                            \"\\nBackup: \" + Arrays.toString(certChecksums));","sourceCodeStart":258,"sourceCodeEnd":294,"githubUrl":"https://github.com/MuntashirAkon/AppManager/blob/0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5/app/src/main/java/io/github/muntashirakon/AppManager/backup/RestoreOp.java#L258-L294","documentation":"restoreApkFiles() requires that the backup flags recorded in the backup (mBackupFlags) indicate APK/source files were included. If the flags say no source files were backed up, restoring the APK is impossible and this BackupException is thrown. It is a flags-vs-content mismatch: the restore request expects an APK payload the backup never contained.","triggerScenarios":"A restore operation that includes APK restoration reaches restoreApkFiles(), and mBackupFlags.backupApkFiles() returns false — the backup metadata's flags do not mark APK files as backed up.","commonSituations":"Restoring a data-only backup while expecting the app itself to be reinstalled; the backup was created with APK backup disabled in App Manager's backup options; backup metadata flags were edited or lost so the flag no longer reflects the files present.","solutions":["Re-create the backup with the 'backup APK/source files' option enabled in App Manager before restoring.","Restore without the APK-restore option and install the app separately (e.g. via Play Store or an APK), then restore data only.","Check the backup's metadata to confirm which flags were used; if flags were tampered with, fix them or regenerate the checksums.","Ensure you selected the right backup for this package — a data-only backup may have been picked where an APK backup was expected."],"exampleFix":"// Conceptual: request data-only restore when the backup has no APKs\n// before\n// restore requested with apk restore -> BackupException\n// after\n// Check flags in App Manager UI before restoring:\n// if (!backupFlags.backupApkFiles()) { installApkManually(); restoreDataOnly(); }","handlingStrategy":"validation","validationCode":"// Check backup flags before requesting restore:\nif (wantApkRestore && !backupFlags.backupApkFiles()) {\n    // install APK separately or recreate the backup with APK files enabled\n}","typeGuard":null,"tryCatchPattern":"try { restoreOp.runRestore(); } catch (BackupException e) {\n    if (e.getMessage().contains(\"backup doesn't contain any source files\")) {\n        // fall back to data-only restore + manual APK install\n    }\n}","preventionTips":["Enable the APK/source backup option when you may need full reinstalls later.","Inspect backup metadata flags before planning a restore.","Keep at least one full (APK + data) backup per important app."],"tags":["android","backup","flags","apk"],"backgroundTag":"missing-required-flag","analyzedSha":"0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5","analyzedAt":"2026-09-12T14:03:37.243Z","contentChangedAt":"2026-09-12T14:03:37.243Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}