MuntashirAkon/AppManager · error · BackupException

Mode

Error message

Mode 

What it means

RestoreOp checks CryptoUtils.isAvailable(mBackupInfo.crypto) after reading backup info and throws BackupException when the crypto mode recorded in the backup is not usable on this device. The message embeds the unavailable mode name after the prefix 'Mode '.

Source

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

    private boolean mRequiresRestart;

    RestoreOp(@NonNull String packageName, @NonNull BackupFlags requestedFlags,
              @NonNull BackupItems.BackupItem backupItem, int userId) throws BackupException {
        mPackageName = packageName;
        mRequestedFlags = requestedFlags;
        mBackupItem = backupItem;
        mUserId = userId;
        try {
            mBackupInfo = mBackupItem.getInfo();
            mBackupFlags = mBackupInfo.flags;
        } catch (IOException e) {
            mBackupItem.cleanup();
            throw new BackupException("Could not read backup info. Possibly due to a malformed json file.", e);
        }
        // Setup crypto
        if (!CryptoUtils.isAvailable(mBackupInfo.crypto)) {
            mBackupItem.cleanup();
            throw new BackupException("Mode " + mBackupInfo.crypto + " is currently unavailable.");
        }
        try {
            mBackupItem.setCrypto(mBackupInfo.getCrypto());
        } catch (CryptoException e) {
            mBackupItem.cleanup();
            throw new BackupException("Could not get crypto " + mBackupInfo.crypto, e);
        }
        try {
            mBackupMetadata = mBackupItem.getMetadata(mBackupInfo).metadata;
        } catch (IOException e) {
            mBackupItem.cleanup();
            throw new BackupException("Could not read backup metadata. Possibly due to a malformed json file.", e);
        }
        // Get checksums
        try {
            mChecksum = mBackupItem.getChecksum();
        } catch (Throwable e) {
            mBackupItem.cleanup();

View on GitHub (pinned to 0152f468fc)

Solutions

  1. Install/enable the missing crypto provider named in the message (e.g. OpenPGP app, MasterCrypt-enabled ROM)
  2. Re-create the backup using a universally available crypto mode (e.g. standard password-based mode) or no encryption
  3. Check CryptoUtils.getMode alternatives supported on the current device before restoring
  4. If the backup was encrypted but you only need unencrypted files, regenerate backup.json with crypto set appropriately

Example fix

// before
if (!CryptoUtils.isAvailable(mBackupInfo.crypto)) {
    throw new BackupException("Mode " + mBackupInfo.crypto + " is currently unavailable.");
}
// after
if (!CryptoUtils.isAvailable(mBackupInfo.crypto)) {
    String[] supported = CryptoUtils.getSupportedModes();
    throw new BackupException("Mode " + mBackupInfo.crypto + " unavailable. Supported: "
            + Arrays.toString(supported) + ". Install the provider or re-create the backup.");
}
Defensive patterns

Strategy: validation

Validate before calling

if (!CryptoUtils.isAvailable(mode)) {
    throw new BackupException("Crypto mode " + mode + " unavailable on this device; install the provider or re-create the backup.");
}

Type guard

boolean modeSupported(String mode) { return mode == null || CryptoUtils.isAvailable(mode); }

Try / catch

try { new RestoreOp(...); } catch (BackupException e) { if (e.getMessage().startsWith("Mode ") && e.getMessage().contains("unavailable")) { installCryptoProviderOrReencrypt(); } throw e; }

Prevention

When it happens

Trigger: backup.json lists a crypto mode (e.g. MasterCrypt, ECryptfs, OpenPGP) that is not installed/usable on the restoring device; isAvailable returns false and the constructor aborts.

Common situations: Backup created on a device with MasterCrypt/ECryptfs support, restored on a stock ROM lacking the kernel module; OpenPGP provider not installed; mode renamed between app versions.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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