MuntashirAkon/AppManager · error · BackupException

External directory containing ${dataSource} is not mounted.

Error message

External directory containing ${dataSource} is not mounted.

What it means

When the target data directory does not exist and it lives on external storage (e.g. /sdcard/Android/data/...), restoreDirectory refuses to create it if dataDirectoryInfo.isMounted reports the external volume is not mounted. Thrown only outside Robolectric tests, where the mount check is skipped. Creating folders on an unmounted volume would silently write to a fake FUSE path, so this is a guard.

Source

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

                    }
                    break;
                case BackupDataDirectoryInfo.TYPE_CREDENTIAL_PROTECTED:
                case BackupDataDirectoryInfo.TYPE_CUSTOM:
                case BackupDataDirectoryInfo.TYPE_DEVICE_PROTECTED:
                    // NOP
                    break;
            }
        } else {
            // Skip if internal data restore is not requested.
            if (!mRequestedFlags.backupInternalData()) {
                return;
            }
        }
        // Create data folder if not exists
        if (!dataSourceFile.exists()) {
            if (dataDirectoryInfo.isExternal() && !dataDirectoryInfo.isMounted) {
                if (!Utils.isRoboUnitTest()) {
                    throw new BackupException("External directory containing " + dataSource + " is not mounted.");
                } // else Skip checking for mounted partition for robolectric tests
            }
            if (!dataSourceFile.mkdirs()) {
                throw new BackupException("Could not create directory " + dataSourceFile);
            }
            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 {

View on GitHub (pinned to 0152f468fc)

Solutions

  1. Mount/remount the external storage (re-insert the SD card) and rerun the restore.
  2. Check Settings > Storage to confirm the volume is mounted and accessible.
  3. For adoptable storage, unlock the device so encrypted storage mounts before restoring.
  4. Move the backup data to internal storage or restore only internal data dirs.

Example fix

// before: restore with SD card removed
ew RestoreOp(...).runRestore(); // throws: not mounted
// after: precondition check in caller
if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
    promptUserToMountSdCard(); // then retry restore
}
runRestore();
Defensive patterns

Strategy: validation

Validate before calling

String state = Environment.getExternalStorageState();
if (!Environment.MEDIA_MOUNTED.equals(state))
    throw new IllegalStateException("External storage must be mounted before restore");

Type guard

boolean isStorageReady(BackupDataDirectoryInfo info) { return !info.isExternal || info.isMounted; }

Try / catch

try { runRestore(); } catch (BackupException e) {
    if (e.getMessage().contains("is not mounted")) {
        requestStorageMount(); // reinsert SD card / unlock adoptable storage, then retry
    } else throw e;
}

Prevention

When it happens

Trigger: Restoring data that includes external-storage directories while the SD card/portable storage is unmounted; USB-OTG storage disconnected; adoptable storage not decrypted after reboot; emulated external storage not yet available at restore time.

Common situations: Restoring to a device whose SD card was removed; restoring before user unlocks/decrypts adoptable storage; automation running restore very early after boot.

Related errors


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