MuntashirAkon/AppManager · error · BackupException

KeyStore files should've existed but they didn't

Error message

KeyStore files should've existed but they didn't

What it means

restoreKeyStore expects the backup item to contain keystore files when a KeyStore restore was requested. getKeyStoreFiles() returned an empty array — the backup claims keystore data but no keystore files are present in the backup directory. AppManager treats this as a broken/incomplete backup.

Solutions

  1. Restore the missing keystore files into the backup directory from the original backup source.
  2. Re-create the backup with keystore capture enabled if the files were never backed up.
  3. Disable the KeyStore restore option if keystore files are intentionally absent.
  4. Verify backup integrity (all files listed in metadata exist) before starting a restore.

Example fix

// before
Path[] keyStoreFiles = mBackupItem.getKeyStoreFiles();
// after
Path[] keyStoreFiles = mBackupItem.getKeyStoreFiles();
if (keyStoreFiles.length == 0 && mRequestedFlags.backupKeyStore()) {
    throw new BackupException("Backup is missing keystore files; re-create the backup");
}
Defensive patterns

Strategy: validation

Validate before calling

Path[] ks = mBackupItem.getKeyStoreFiles();
if (flags.backupKeyStore() && ks.length == 0) throw new IllegalStateException("Backup missing keystore files");

Try / catch

if (keyStoreFiles.length == 0) { throw new BackupException("KeyStore files should've existed but they didn't"); } // catch and either re-create backup or disable keystore flag

Prevention

When it happens

Trigger: mBackupItem.getKeyStoreFiles() returns length 0: the keystore.tar* files were deleted from the backup folder, the backup was created without keystore capture, or the backup item's file listing is stale.

Common situations: Manually copying backups and omitting keystore files; storage cleaners deleting 'unused' files; backups created before keystore support was added; corrupted backup manifest not matching on-disk contents.

Understand the failure class

Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.

Related errors


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

Appendix: source

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

                mIsInstalled = true;
            } catch (Exception e) {
                throw new BackupException("Apparently the install wasn't complete in the previous section.", e);
            }
        }
    }

    private void restoreKeyStore() throws BackupException {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            // keystore v2 is not supported.
            Log.w(TAG, "Ignoring KeyStore backups for %s", mPackageName);
            return;
        }
        if (mPackageInfo == null) {
            throw new BackupException("KeyStore restore is requested but the app isn't installed.");
        }
        Path[] keyStoreFiles = mBackupItem.getKeyStoreFiles();
        if (keyStoreFiles.length == 0) {
            throw new BackupException("KeyStore files should've existed but they didn't");
        }
        if (!mRequestedFlags.skipSignatureCheck()) {
            String checksum;
            for (Path file : keyStoreFiles) {
                checksum = DigestUtils.getHexDigest(mBackupInfo.checksumAlgo, file);
                if (!checksum.equals(mChecksum.get(file.getName()))) {
                    throw new BackupException("KeyStore file verification failed." +
                            "\nFile: " + file +
                            "\nFound: " + checksum +
                            "\nRequired: " + mChecksum.get(file.getName()));
                }
            }
        }
        // Decrypt sources
        try {
            keyStoreFiles = mBackupItem.decrypt(keyStoreFiles);
        } catch (IOException e) {
            throw new BackupException("Failed to decrypt " + Arrays.toString(keyStoreFiles), e);

View on GitHub (pinned to 0152f468fc)