MuntashirAkon/AppManager · error · BackupException

Failed to write metadata.

Error message

Failed to write metadata.

What it means

BackupOp wraps IOException from MetadataManager.writeMetadata() in a BackupException with this message. The metadata file (containing backup flags, version codes, timestamps, checksums) could not be serialized and written into the backup directory. Without it the backup cannot be restored, so the whole operation fails.

Source

Thrown at app/src/main/java/io/github/muntashirakon/AppManager/backup/BackupOp.java:193

            }
            // Backup extras
            if (mBackupFlags.backupExtras()) {
                backupExtras();
                incrementProgress(progressHandler);
            }
            // Export rules
            if (mMetadata.metadata.hasRules) {
                backupRules();
                incrementProgress(progressHandler);
            }
            // Write modified metadata
            try {
                Map<String, String> filenameChecksumMap = MetadataManager.writeMetadata(mMetadata, mBackupItem);
                for (Map.Entry<String, String> entry : filenameChecksumMap.entrySet()) {
                    mChecksum.add(entry.getKey(), entry.getValue());
                }
            } catch (IOException e) {
                throw new BackupException("Failed to write metadata.", e);
            }
            mChecksum.close();
            // Encrypt checksum
            try {
                mBackupItem.encrypt(new Path[]{mChecksum.getFile()});
            } catch (IOException e) {
                throw new BackupException("Failed to write checksums.txt", e);
            }
            // Replace current backup
            try {
                mBackupItem.commit();
            } catch (IOException e) {
                throw new BackupException("Could not finalise backup.", e);
            }
        } catch (BackupException e) {
            throw e;
        } catch (Throwable th) {
            throw new BackupException("Unknown error occurred.", th);

View on GitHub (pinned to 0152f468fc)

Solutions

  1. Verify free space on the backup storage volume.
  2. Confirm the backup destination path is writable (re-grant SAF/storage permissions).
  3. Check the chained IOException's message for the exact path and reason.
  4. Delete any partially written backup directory and retry the backup.

Example fix

// before
mBackupItem = new BackupItems(...); // writes to stale SAF dir
// after
if (!mBackupItem.getUnencryptedBackupPath().canWrite()) {
    throw new IOException("Backup destination not writable"); // fix permissions first
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (backupDest.getUsableSpace() < 100*1024*1024 || !backupDest.canWrite()) { throw new IOException("Destination not writable or full"); }

Type guard

boolean isWritableDir(Path p) { return p != null && p.isDirectory() && p.canWrite(); }

Try / catch

try {
    backupOp.runBackup(progress);
} catch (BackupException e) {
    if (e.getMessage().equals("Failed to write metadata.")) {
        Log.e(TAG, "metadata write failed", (IOException) e.getCause());
    }
}

Prevention

When it happens

Trigger: MetadataManager.writeMetadata(mMetadata, mBackupItem) throws IOException while creating or writing the metadata JSON file into the backup item's storage.

Common situations: Backup destination is full or read-only (external SD card, SAF document provider denied write); the backup directory was deleted mid-operation; disk I/O errors.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


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