MuntashirAkon/AppManager · error · BackupException

Failed to restore data files for index ${index}.

Error message

Failed to restore data files for index ${index}.

What it means

restoreDirectory extracts the decrypted data archives into the target directory via TarUtils.extract, wrapping any Throwable in this BackupException tagged with the data directory index. It means the tar (gzip/zstd etc.) archives could not be unpacked — corrupt archive, unsupported compression, or extraction I/O failure.

Source

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

            }
            if (!dataDirectoryInfo.isExternal()) {
                // Restore UID, GID
                dataSourceFile.setUidGid(uidGidPair);
            }
        }
        // Decrypt data
        try {
            dataFiles = mBackupItem.decrypt(dataFiles);
        } catch (IOException e) {
            throw new BackupException("Failed to decrypt " + Arrays.toString(dataFiles), e);
        }
        // Extract data to the data directory
        try {
            String publicSourceDir = new File(Objects.requireNonNull(mPackageInfo.applicationInfo).publicSourceDir).getParent();
            TarUtils.extract(mBackupInfo.tarType, dataFiles, dataSourceFile, null, BackupUtils
                    .getExcludeDirs(!mRequestedFlags.backupCache(), null), publicSourceDir);
        } catch (Throwable th) {
            throw new BackupException("Failed to restore data files for index " + index + ".", th);
        }
        // Restore UID and GID
        if (!Runner.runCommand(String.format(Locale.ROOT, "chown -R %d:%d \"%s\"", uidGidPair.uid, uidGidPair.gid, dataSourceFile.getFilePath())).isSuccessful()) {
            if (!Utils.isRoboUnitTest()) {
                throw new BackupException("Failed to restore ownership info for index " + index + ".");
            } // else Don't care about permissions
        }
        // Restore context
        if (!dataDirectoryInfo.isExternal()) {
            Runner.runCommand(new String[]{"restorecon", "-R", dataSourceFile.getFilePath()});
        }
    }

    private void restoreAdb(int index) throws BackupException {
        Path[] dataFiles = mBackupItem.getDataFiles(index);
        if (dataFiles.length != 1) {
            throw new BackupException("ADB restore is requested but there are no .ab files.");
        }

View on GitHub (pinned to 0152f468fc)

Solutions

  1. Free up storage space on the target partition and retry the restore.
  2. Verify the data archives are complete (sizes/checksums) and re-copy from the original source if truncated.
  3. Confirm the compression format is supported on the device (install/enable the matching busybox/toybox tooling) or re-create the backup with gzip.
  4. Check the wrapped cause for the exact tar error (bad header vs. write failure).
  5. Update App Manager on both ends so backup (tarType) and restore versions match.

Example fix

// before: restoring truncated archive
new RestoreOp(...).runRestore(); // BackupException: failed to restore data files for index 0
// after: validate archive before restore
if (!isCompleteTarArchive(dataFile)) { // e.g. test via tar -tf
    reCopyFromOriginalBackup();
}
runRestore();
Defensive patterns

Strategy: retry

Validate before calling

// Sanity-check archives are non-empty before extraction
for (Path f : dataFiles) {
    if (Files.size(f) == 0) throw new IllegalStateException("Empty archive: " + f);
}

Type guard

boolean extractable(Path[] files) { return files.length > 0 && Files.exists(files[0]) && files[0].size() > 0; }

Try / catch

try { runRestore(); } catch (BackupException e) {
    if (e.getMessage().contains("Failed to restore data files")) {
        Log.e(TAG, "tar extract failed", e.getCause()); // inspect tar error
        freeSpaceThenRetry();
    } else throw e;
}

Prevention

When it happens

Trigger: TarUtils.extract throws: corrupt/truncated .tar or .tar.gz; archive compressed with a format the device's tar doesn't support (e.g. zstd binaries missing); target filesystem full or read-only mid-extract; exclusion/SELinux path issues passing an invalid publicSourceDir.

Common situations: Backups compressed with a newer tool than the restore environment supports; partial downloads/syncs producing truncated archives; restoring onto full internal storage; App Manager version mismatch changing tarType handling.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


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