{"record":{"id":"b162ae80da397698","repo":"MuntashirAkon/AppManager","slug":"failed-to-access-properties-of-the-keystore-folder","errorCode":null,"errorMessage":"Failed to access properties of the KeyStore folder.","messagePattern":"Failed to access properties of the KeyStore folder\\.","errorType":"exception","errorClass":"BackupException","httpStatus":null,"severity":"error","filePath":"app/src/main/java/io/github/muntashirakon/AppManager/backup/RestoreOp.java","lineNumber":451,"sourceCode":"                }\n            }\n        }\n        // Decrypt sources\n        try {\n            keyStoreFiles = mBackupItem.decrypt(keyStoreFiles);\n        } catch (IOException e) {\n            throw new BackupException(\"Failed to decrypt \" + Arrays.toString(keyStoreFiles), e);\n        }\n        // Restore KeyStore files to the /data/misc/keystore folder\n        Path keyStorePath = KeyStoreUtils.getKeyStorePath(mUserId);\n        // Note down UID/GID\n        UidGidPair uidGidPair;\n        int mode;\n        try {\n            uidGidPair = Objects.requireNonNull(keyStorePath.getFile()).getUidGid();\n            mode = keyStorePath.getFile().getMode();\n        } catch (ErrnoException e) {\n            throw new BackupException(\"Failed to access properties of the KeyStore folder.\", e);\n        }\n        try {\n            TarUtils.extract(mBackupInfo.tarType, keyStoreFiles, keyStorePath, null, null, null);\n            // Restore folder permission\n            Paths.chown(keyStorePath, uidGidPair.uid, uidGidPair.gid);\n            //noinspection OctalInteger\n            Paths.chmod(keyStorePath, mode & 0777);\n        } catch (Throwable th) {\n            throw new BackupException(\"Failed to restore the KeyStore files.\", th);\n        }\n        // Rename files\n        List<String> keyStoreFileNames = KeyStoreUtils.getKeyStoreFiles(KEYSTORE_PLACEHOLDER, mUserId);\n        for (String keyStoreFileName : keyStoreFileNames) {\n            try {\n                String newFilename = Utils.replaceOnce(keyStoreFileName, String.valueOf(KEYSTORE_PLACEHOLDER), String.valueOf(mUid));\n                keyStorePath.findFile(keyStoreFileName).renameTo(newFilename);\n                Path targetFile = keyStorePath.findFile(newFilename);\n                // Restore file permission","sourceCodeStart":433,"sourceCodeEnd":469,"githubUrl":"https://github.com/MuntashirAkon/AppManager/blob/0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5/app/src/main/java/io/github/muntashirakon/AppManager/backup/RestoreOp.java#L433-L469","documentation":"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.","triggerScenarios":"keyStorePath.getFile().getUidGid() or getMode() throws ErrnoException: /data/misc/keystore does not exist for mUserId, or the process lacks root/permission to stat it.","commonSituations":"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.","solutions":["Ensure AppManager is running with root (or the required privileged mode) before restoring keystore.","Verify /data/misc/keystore (per mUserId) exists; create or boot the device so the directory is initialized.","Check SELinux denials in logcat and use a mode that permits stat on the keystore folder.","Abort keystore restore on non-standard ROMs where the keystore path differs."],"exampleFix":"// before\nuidGidPair = Objects.requireNonNull(keyStorePath.getFile()).getUidGid();\nmode = keyStorePath.getFile().getMode();\n// after\nFile ksFile = keyStorePath.getFile();\nif (ksFile == null || !ksFile.exists()) {\n    throw new BackupException(\"KeyStore folder does not exist for user \" + mUserId);\n}\nuidGidPair = ksFile.getUidGid();\nmode = ksFile.getMode();","handlingStrategy":"try-catch","validationCode":"File ks = keyStorePath.getFile();\nif (ks == null || !ks.exists()) throw new ErrnoException(\"keystore-path\", OsConstants.ENOENT);\nif (!isPrivileged()) throw new SecurityException(\"Root required for keystore restore\");","typeGuard":"boolean canStatKeystore(Path p) { try { return p.getFile() != null && p.getFile().exists(); } catch (Exception e) { return false; } }","tryCatchPattern":"try { uidGidPair = ksFile.getUidGid(); mode = ksFile.getMode(); } catch (ErrnoException e) { throw new BackupException(\"Failed to access properties of the KeyStore folder.\", e); }","preventionTips":["Run the restore with root privileges when touching /data/misc/keystore","Verify the per-user keystore directory exists before starting","Check SELinux audit logs for stat denials on keystore paths","Skip keystore restore on ROMs with non-standard keystore locations"],"tags":["android","keystore","filesystem","root"],"backgroundTag":"permission-denied","analyzedSha":"0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5","analyzedAt":"2026-09-12T14:03:37.243Z","contentChangedAt":"2026-09-12T14:03:37.243Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}