MuntashirAkon/AppManager · error · BackupException

Source file verification failed.\nFile

Error message

Source file verification failed.\nFile: ${file}\nFound: ${checksum}\nRequired: ${mChecksum.get(file.getName())}

What it means

As part of restoreApkFiles(), each backed-up source file is hashed with the backup's checksum algorithm and compared with the checksum recorded in the checksum file. Any divergence aborts the restore with this BackupException, protecting against corrupted or tampered APK archives. Message includes the file path, computed checksum, and required checksum.

Solutions

  1. Re-copy the backup set from its original source and retry; the failing file is likely truncated or corrupted.
  2. Verify storage media health (SD card errors are a common cause) and free space at the destination.
  3. If you intentionally modified a source file, recompute its checksum and update the checksums file with the same algorithm.
  4. Confirm the checksums file corresponds to this backup; restore the correct one if backup sets were mixed.
Defensive patterns

Strategy: validation

Validate before calling

// Pre-verify every source file before restore:
for (Path f : backupItem.getSourceFiles()) {
    String found = DigestUtils.getHexDigest(info.checksumAlgo, f);
    if (!found.equals(checksums.get(f.getName()))) {
        // re-copy the corrupted file before invoking restore
    }
}

Try / catch

try { restoreOp.runRestore(); } catch (BackupException e) {
    if (e.getMessage().startsWith("Source file verification failed")) {
        // extract File/Found/Required from message; re-transfer that file
    }
}

Prevention

When it happens

Trigger: For a file in backupSourceFiles, DigestUtils.getHexDigest(mBackupInfo.checksumAlgo, file) != mChecksum.get(file.getName()) while skipSignatureCheck() is false.

Common situations: Incomplete/corrupted transfer of the backup folder (cloud sync truncation, bad SD card); backup files modified after creation; wrong checksums file placed alongside the backup; checksum algorithm changed between backup and restore.

Understand the failure class

Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.

Related errors


AI-assisted analysis of MuntashirAkon/AppManager@0152f468fc (2026-09-12). Data as JSON: /api/errors/fee60866afbeb7ce. Report an issue: GitHub.

Appendix: source

Thrown at app/src/main/java/io/github/muntashirakon/AppManager/backup/RestoreOp.java:303

            // Check signature of the installed app
            List<String> certChecksumList = Arrays.asList(PackageUtils.getSigningCertChecksums(mBackupInfo.checksumAlgo, mPackageInfo, false));
            String[] certChecksums = BackupItems.Checksum.getCertChecksums(mChecksum);
            for (String checksum : certChecksums) {
                if (certChecksumList.contains(checksum)) continue;
                isVerified = false;
                if (!mRequestedFlags.skipSignatureCheck()) {
                    throw new BackupException("Signing info verification failed." +
                            "\nInstalled: " + certChecksumList +
                            "\nBackup: " + Arrays.toString(certChecksums));
                }
            }
        }
        if (!mRequestedFlags.skipSignatureCheck()) {
            String checksum;
            for (Path file : backupSourceFiles) {
                checksum = DigestUtils.getHexDigest(mBackupInfo.checksumAlgo, file);
                if (!checksum.equals(mChecksum.get(file.getName()))) {
                    throw new BackupException("Source file verification failed." +
                            "\nFile: " + file +
                            "\nFound: " + checksum +
                            "\nRequired: " + mChecksum.get(file.getName()));
                }
            }
        }
        if (!isVerified) {
            // Signature verification failed but still here because signature check is disabled.
            // The only way to restore is to reinstall the app
            synchronized (sLock) {
                PackageInstallerCompat installer = PackageInstallerCompat.getNewInstance();
                if (installer.uninstall(mPackageName, mUserId, false)) {
                    throw new BackupException("An uninstallation was necessary but couldn't perform it.");
                }
            }
        }
        // Setup package staging directory
        Path packageStagingDirectory = Paths.get(PackageUtils.PACKAGE_STAGING_DIRECTORY);

View on GitHub (pinned to 0152f468fc)