{"record":{"id":"53290da039c0905f","repo":"MuntashirAkon/AppManager","slug":"data-file-verification-failed-for-index-i-nfile-file-nfound","errorCode":null,"errorMessage":"Data file verification failed for index ${i}.\\nFile: ${file}\\nFound: ${checksum}\\nRequired: ${mChecksum.get(file.getName())}","messagePattern":"Data file verification failed for index (.+?)\\.\\\\nFile: (.+?)\\\\nFound: (.+?)\\\\nRequired: (.+?)","errorType":"exception","errorClass":"BackupException","httpStatus":null,"severity":"critical","filePath":"app/src/main/java/io/github/muntashirakon/AppManager/backup/RestoreOp.java","lineNumber":497,"sourceCode":"\n    private void restoreData() throws BackupException {\n        // Data restore is requested: Data restore is only possible if the app is actually\n        // installed. So, check if it's installed first.\n        if (mPackageInfo == null) {\n            throw new BackupException(\"Data restore is requested but the app isn't installed.\");\n        }\n        if (!mRequestedFlags.skipSignatureCheck()) {\n            // Verify integrity of the data backups\n            String checksum;\n            for (int i = 0; i < mBackupMetadata.dataDirs.length; ++i) {\n                Path[] dataFiles = mBackupItem.getDataFiles(i);\n                if (dataFiles.length == 0) {\n                    throw new BackupException(\"Data restore is requested but there are no data files for index \" + i + \".\");\n                }\n                for (Path file : dataFiles) {\n                    checksum = DigestUtils.getHexDigest(mBackupInfo.checksumAlgo, file);\n                    if (!checksum.equals(mChecksum.get(file.getName()))) {\n                        throw new BackupException(\"Data file verification failed for index \" + i + \".\" +\n                                \"\\nFile: \" + file +\n                                \"\\nFound: \" + checksum +\n                                \"\\nRequired: \" + mChecksum.get(file.getName()));\n                    }\n                }\n            }\n        }\n        // Force-stop and clear app data\n        PackageManagerCompat.clearApplicationUserData(mPackageName, mUserId);\n        // Restore backups\n        for (int i = 0; i < mBackupMetadata.dataDirs.length; ++i) {\n            String backupDataDir = mBackupMetadata.dataDirs[i];\n            if (backupDataDir.equals(BackupManager.DATA_BACKUP_SPECIAL_ADB)) {\n                // Adb backup restore\n                restoreAdb(i);\n            } else {\n                // Regular directory restore\n                restoreDirectory(mBackupMetadata.dataDirs[i], i);","sourceCodeStart":479,"sourceCodeEnd":515,"githubUrl":"https://github.com/MuntashirAkon/AppManager/blob/0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5/app/src/main/java/io/github/muntashirakon/AppManager/backup/RestoreOp.java#L479-L515","documentation":"Integrity verification in restoreData computes the digest of each data backup file with mBackupInfo.checksumAlgo and compares it to the value recorded in mChecksum. If the computed checksum differs from the expected one, this BackupException is thrown with the file, found and required digests. It guarantees a data backup was modified or corrupted after being created.","triggerScenarios":"Any data backup file's digest mismatches the checksums file: file edited/truncated in place, corrupted transfer, wrong checksum algorithm applied, or checksums file regenerated while data files changed.","commonSituations":"Backups synced via cloud/USB with corruption; user renamed/recompressed tar files; restoring a backup that was modified by another tool; checksum algorithm (e.g. MD5 vs SHA-256) mismatch after a version change.","solutions":["Re-copy the backup from its original source and retry — the file was likely corrupted in transit.","Re-create the backup from a healthy installation; the data files cannot be trusted.","Verify mBackupInfo.checksumAlgo matches the algorithm used to generate the checksums file.","As a last resort, skip signature check via skipSignatureCheck() flag, accepting the risk of corrupt data."],"exampleFix":"// before: restoring after suspicious transfer\new RestoreOp(...).runRestore(); // BackupException: verification failed\n// after: verify manually first\nString found = DigestUtils.getHexDigest(\"SHA-256\", dataFile);\nString expected = checksums.get(dataFile.getName());\nif (!found.equals(expected)) {\n    reCopyBackupFromSource(); // then restore\n}","handlingStrategy":"validation","validationCode":"String found = DigestUtils.getHexDigest(info.checksumAlgo, dataFile);\nif (!found.equals(checksums.get(dataFile.getName())))\n    throw new IllegalStateException(\"Corrupt backup file: \" + dataFile);\n","typeGuard":"boolean checksumOk(Map<String,String> sums, String algo, Path f) {\n    return sums.containsKey(f.getName()) &&\n        sums.get(f.getName()).equals(DigestUtils.getHexDigest(algo, f));\n}","tryCatchPattern":"try { runRestore(); } catch (BackupException e) {\n    if (e.getMessage().contains(\"Data file verification failed\")) {\n        // message embeds File/Found/Required lines — log and re-fetch backup\n        Log.e(TAG, e.getMessage());\n        reCopyBackupAndRetry();\n    } else throw e;\n}","preventionTips":["Transfer backups via checksum-verified channels (checksum after copy).","Never edit or recompress backup archives in place.","Keep the checksums file together with the archives.","Verify backups right after creation, before archiving them away."],"tags":["android","backup","checksum","integrity","corruption"],"backgroundTag":"checksum-mismatch","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"}