MuntashirAkon/AppManager · error · BackupException

Failed to encrypt [ ]

Error message

Failed to encrypt [${sourceFiles}]

What it means

After re-packaging, backupApkFile() encrypts the produced archive files via mBackupItem.encrypt(sourceFiles); an IOException is wrapped as this message including the file list (no cause preserved). It means encryption of the APK archive files failed.

Solutions

  1. Validate the destination crypto settings (key alias, algorithm) before conversion; re-select or recreate the encryption key.
  2. Check free space and writability of the destination backup path.
  3. Delete stale .enc files from a previous failed conversion and retry.
  4. Inspect crypto-layer logs, since this BackupException drops the original IOException cause (add `e` as cause when editing the library).

Example fix

// before
throw new BackupException("Failed to encrypt " + Arrays.toString(sourceFiles));
// after
throw new BackupException("Failed to encrypt " + Arrays.toString(sourceFiles), e); // keep cause
Defensive patterns

Strategy: validation

Validate before calling

// Pre-check crypto readiness before conversion
if (mBackupItem.isEncrypted() && !CryptoUtils.keyExists(destCrypto.keyAlias)) {
    throw new IllegalStateException("Encryption key for alias not found: " + destCrypto.keyAlias);
}

Type guard

fun CryptoInfo?.canEncryptFiles(): Boolean =
    this != null && keyAlias != null && algo != null && CryptoUtils.keyExists(keyAlias)

Try / catch

try {
    converter.convert();
} catch (BackupException e) {
    if (e.getMessage() != null && e.getMessage().startsWith("Failed to encrypt [")) {
        Log.e(TAG, "APK encryption failed for files listed in message — verify keystore/algorithm");
    }
}

Prevention

When it happens

Trigger: mBackupItem.encrypt(sourceFiles) throws IOException: crypto engine cannot initialize (missing/invalid keystore key or alias), unsupported algorithm for the destination format, or I/O failure reading plaintext/writing ciphertext.

Common situations: Keystore deleted or key invalidated between metadata generation and encryption; destination crypto algorithm mismatched with the selected key; storage full or ciphertext files unreplaceable from a previous failed run.

Related errors


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

Appendix: source

Thrown at app/src/main/java/io/github/muntashirakon/AppManager/backup/convert/TBConverter.java:235

        } catch (Exception ignore) {
        }
        // Backup APK file
        String sourceBackupFilePrefix = BackupUtils.getSourceFilePrefix(getExt(mDestMetadata.info.tarType));
        Path[] sourceFiles;
        try {
            sourceFiles = TarUtils.create(mDestMetadata.info.tarType, baseApkFile, mBackupItem.getUnencryptedBackupPath(), sourceBackupFilePrefix,
                            /* language=regexp */new String[]{".*\\.apk"}, null, null, false)
                    .toArray(new Path[0]);
        } catch (Throwable th) {
            throw new BackupException("APK files backup is requested but no APK files have been backed up.", th);
        } finally {
            baseApkFile.requireParent().delete();
        }
        // Overwrite with the new files
        try {
            sourceFiles = mBackupItem.encrypt(sourceFiles);
        } catch (IOException e) {
            throw new BackupException("Failed to encrypt " + Arrays.toString(sourceFiles));
        }
        for (Path file : sourceFiles) {
            mChecksum.add(file.getName(), DigestUtils.getHexDigest(mDestMetadata.info.checksumAlgo, file));
        }
    }

    private void backupData() throws BackupException {
        Path dataFile;
        try {
            dataFile = getDataFile(Paths.trimPathExtension(mPropFile.getName()), mSourceMetadata.tarType);
        } catch (FileNotFoundException e) {
            throw new BackupException("Could not get data file", e);
        }
        String tarType = mDestMetadata.info.tarType;
        int i = 0;
        String intBackupFilePrefix = null;
        String extBackupFilePrefix = null;
        if (mDestMetadata.info.flags.backupInternalData()) {

View on GitHub (pinned to 0152f468fc)