MuntashirAkon/AppManager · critical · KeyStoreException

No saved password for KeyStore.

Error message

No saved password for KeyStore.

What it means

getAmKeyStorePassword reads the encrypted AM keystore password from shared preferences and decrypts it. If no password has ever been saved (PREF_AM_KEYSTORE_PASS absent), it throws KeyStoreException — meaning the AM keystore was never initialized with a password, so keystore operations requiring the password cannot proceed.

Solutions

  1. Initialize the keystore by adding a key (addKeyPair/addSecretKey), which creates and persists the password
  2. Detect the missing preference and run first-time keystore setup before any keystore read
  3. If the keystore file itself was lost with the data, start a fresh keystore

Example fix

// before
char[] pass = ksManager.getAmKeyStorePassword(); // throws on fresh install
// after
if (PreferenceManager.getDefaultSharedPreferences(ctx).contains(KeyStoreManager.PREF_AM_KEYSTORE_PASS)) {
    char[] pass = ksManager.getAmKeyStorePassword();
} else {
    ksManager.addKeyPair(alias, keyPair, newPassword, false); // initializes password
}
Defensive patterns

Strategy: try-catch

Validate before calling

boolean initialized = PreferenceManager.getDefaultSharedPreferences(ctx)
        .contains(KeyStoreManager.PREF_AM_KEYSTORE_PASS);
if (!initialized) {
    runFirstTimeKeystoreSetup();
}

Try / catch

try {
    char[] pass = ksManager.getAmKeyStorePassword();
} catch (KeyStoreException e) {
    // no stored password: keystore never initialized or data cleared
    initializeKeystore();
}

Prevention

When it happens

Trigger: Calling getAmKeyStorePassword (via password()/realPassword()) before any key was added to the AM keystore (addKeyPair/addSecretKey never ran), or after app data/keystore was wiped.

Common situations: Fresh install querying keys before initialization; cleared app data losing the shared-preferences entry while the keystore file survives; restore that skipped shared preferences.

Understand the failure class

Background: "missing required config value" errors: why libraries refuse to start when a configuration key is empty, unset, or blank — this error's family across 48 libraries.

Related errors


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

Appendix: source

Thrown at app/src/main/java/io/github/muntashirakon/AppManager/crypto/ks/KeyStoreManager.java:477

            Utils.clearChars(realPassword);
        }
        return keyStore;
    }

    /**
     * Get App Manager's KeyStore password. The password is stored in the shared preferences in an
     * encrypted format (the encryption/decryption is performed via AndroidKeyStore). In case the
     * user restores from the cache or accidentally deletes all entries from the shared pref, App
     * Manager will ask for KeyStore password again.
     *
     * @return KeyStore password in decrypted format. {@link Utils#clearChars(char[])} must be called when done.
     */
    @CheckResult
    @NonNull
    public char[] getAmKeyStorePassword() throws KeyStoreException {
        String encryptedPass = sSharedPreferences.getString(PREF_AM_KEYSTORE_PASS, null);
        if (encryptedPass == null) {
            throw new KeyStoreException("No saved password for KeyStore.");
        }
        char[] realPassword = getDecryptedPassword(mContext, encryptedPass);
        if (realPassword == null) {
            throw new KeyStoreException("Could not decrypt encrypted password.");
        }
        return realPassword;
    }

    /**
     * @return Password for the given alias. {@link Utils#clearChars(char[])} must be called when done.
     * @deprecated Kept for migratory purposes only, deprecated since v2.6.3. To be removed in v3.0.0.
     */
    @Deprecated
    @CheckResult
    @NonNull
    private char[] getAliasPassword(@NonNull String alias) throws KeyStoreException {
        char[] password;
        String prefAlias = getPrefAlias(alias);

View on GitHub (pinned to 0152f468fc)