MuntashirAkon/AppManager · error · KeyStoreException
The alias does not have a KeyPair.
Error message
The alias ${alias} does not have a KeyPair. What it means
getSecretKey retrieves the key stored under an alias and requires it to be a SecretKey. If getKey returns a key of any other type (e.g. a PrivateKey), the alias does not hold a secret key, and a KeyStoreException with this message is thrown. Note the message text says 'KeyPair' but the actual expectation is a SecretKey.
Solutions
- Use the correct alias that was stored via addSecretKey
- Call getKeyPair(alias) instead if the alias holds a KeyPair
- Check the stored entry type with getKey/containsAlias before choosing the accessor
Example fix
// before
SecretKey key = ksManager.getSecretKey("my-signing-key"); // wrong: alias holds a KeyPair
// after
KeyPair kp = ksManager.getKeyPair("my-signing-key");
SecretKey key = ksManager.getSecretKey("my-aes-key"); Defensive patterns
Strategy: validation
Validate before calling
Key key = ksManager.getKey(alias);
if (!(key instanceof SecretKey)) {
throw new IllegalArgumentException("Alias does not hold a SecretKey");
} Type guard
boolean isSecretKey(Key k) {
return k instanceof SecretKey;
} Try / catch
try {
SecretKey sk = ksManager.getSecretKey(alias);
} catch (KeyStoreException e) {
// alias holds another key type; fall back to getKeyPair or regenerate
} Prevention
- Keep separate alias namespaces for secret keys vs key pairs
- Use getKey/instanceof to check entry type before accessor choice
- Fix or rely on the (misleading) message text accordingly when reporting bugs
When it happens
Trigger: Calling getSecretKey(alias) for an alias that holds a private/certificate entry instead of a secret key, or an alias whose key was stored with the wrong entry type (misleading message).
Common situations: Using an alias reserved for signing key pairs with the AES crypto API; migration storing keys under wrong types; alias mix-ups between KeyPair and SecretKey namespaces.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Could not decrypt encrypted password.
- Could not get crypto " + mBackupInfo.crypto
- Could not load AES local protection key from keystore
- Decrypted pass is empty for alias
- Failed to get crypto
AI-assisted analysis of MuntashirAkon/AppManager@0152f468fc (2026-09-12).
Data as JSON: /api/errors/0e3ae9c7aa33cb83.
Report an issue: GitHub.
Appendix: source
Thrown at app/src/main/java/io/github/muntashirakon/AppManager/crypto/ks/KeyStoreManager.java:356
@Nullable
private Key getKey(String alias, @Nullable char[] password)
throws UnrecoverableKeyException, NoSuchAlgorithmException, KeyStoreException {
if (password == null) {
password = getAliasPassword(alias);
}
Key key = mAmKeyStore.getKey(alias, password);
Utils.clearChars(password);
return key;
}
@Nullable
public SecretKey getSecretKey(String alias)
throws UnrecoverableKeyException, NoSuchAlgorithmException, KeyStoreException {
Key key = getKey(alias);
if (key instanceof SecretKey) {
return (SecretKey) key;
}
throw new KeyStoreException("The alias " + alias + " does not have a KeyPair.");
}
@Nullable
public KeyPair getKeyPair(String alias)
throws UnrecoverableKeyException, NoSuchAlgorithmException, KeyStoreException {
Key key = getKey(alias);
if (key instanceof PrivateKey) {
return new KeyPair((PrivateKey) key, getCertificate(alias));
}
throw new KeyStoreException("The alias " + alias + " does not have a KeyPair.");
}
@Nullable
public KeyPair getKeyPairNoThrow(String alias) {
try {
return getKeyPair(alias);
} catch (Exception e) {
return null;View on GitHub (pinned to 0152f468fc)