MuntashirAkon/AppManager · error · BackupException

Failed to access properties of the KeyStore folder.

Error message

Failed to access properties of the KeyStore folder.

What it means

Before extracting keystore files into /data/misc/keystore, restoreKeyStore reads that folder's UID/GID and permission mode so ownership can be restored after extraction. This error means querying those properties threw an ErrnoException — the keystore directory could not be stat'd. Without them, AppManager cannot safely restore ownership, so it aborts.

Source

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

                }
            }
        }
        // Decrypt sources
        try {
            keyStoreFiles = mBackupItem.decrypt(keyStoreFiles);
        } catch (IOException e) {
            throw new BackupException("Failed to decrypt " + Arrays.toString(keyStoreFiles), e);
        }
        // Restore KeyStore files to the /data/misc/keystore folder
        Path keyStorePath = KeyStoreUtils.getKeyStorePath(mUserId);
        // Note down UID/GID
        UidGidPair uidGidPair;
        int mode;
        try {
            uidGidPair = Objects.requireNonNull(keyStorePath.getFile()).getUidGid();
            mode = keyStorePath.getFile().getMode();
        } catch (ErrnoException e) {
            throw new BackupException("Failed to access properties of the KeyStore folder.", e);
        }
        try {
            TarUtils.extract(mBackupInfo.tarType, keyStoreFiles, keyStorePath, null, null, null);
            // Restore folder permission
            Paths.chown(keyStorePath, uidGidPair.uid, uidGidPair.gid);
            //noinspection OctalInteger
            Paths.chmod(keyStorePath, mode & 0777);
        } catch (Throwable th) {
            throw new BackupException("Failed to restore the KeyStore files.", th);
        }
        // Rename files
        List<String> keyStoreFileNames = KeyStoreUtils.getKeyStoreFiles(KEYSTORE_PLACEHOLDER, mUserId);
        for (String keyStoreFileName : keyStoreFileNames) {
            try {
                String newFilename = Utils.replaceOnce(keyStoreFileName, String.valueOf(KEYSTORE_PLACEHOLDER), String.valueOf(mUid));
                keyStorePath.findFile(keyStoreFileName).renameTo(newFilename);
                Path targetFile = keyStorePath.findFile(newFilename);
                // Restore file permission

View on GitHub (pinned to 0152f468fc)

Solutions

  1. Ensure AppManager is running with root (or the required privileged mode) before restoring keystore.
  2. Verify /data/misc/keystore (per mUserId) exists; create or boot the device so the directory is initialized.
  3. Check SELinux denials in logcat and use a mode that permits stat on the keystore folder.
  4. Abort keystore restore on non-standard ROMs where the keystore path differs.

Example fix

// before
uidGidPair = Objects.requireNonNull(keyStorePath.getFile()).getUidGid();
mode = keyStorePath.getFile().getMode();
// after
File ksFile = keyStorePath.getFile();
if (ksFile == null || !ksFile.exists()) {
    throw new BackupException("KeyStore folder does not exist for user " + mUserId);
}
uidGidPair = ksFile.getUidGid();
mode = ksFile.getMode();
Defensive patterns

Strategy: try-catch

Validate before calling

File ks = keyStorePath.getFile();
if (ks == null || !ks.exists()) throw new ErrnoException("keystore-path", OsConstants.ENOENT);
if (!isPrivileged()) throw new SecurityException("Root required for keystore restore");

Type guard

boolean canStatKeystore(Path p) { try { return p.getFile() != null && p.getFile().exists(); } catch (Exception e) { return false; } }

Try / catch

try { uidGidPair = ksFile.getUidGid(); mode = ksFile.getMode(); } catch (ErrnoException e) { throw new BackupException("Failed to access properties of the KeyStore folder.", e); }

Prevention

When it happens

Trigger: keyStorePath.getFile().getUidGid() or getMode() throws ErrnoException: /data/misc/keystore does not exist for mUserId, or the process lacks root/permission to stat it.

Common situations: Running without root/adb privileges; non-standard ROMs with a different keystore path; multi-user setups where the per-user keystore directory is absent; SELinux denials on stat.

Understand the failure class

Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.

Related errors


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