{"record":{"id":"ee5b6eff383e9289","repo":"shwenzhang/AndResGuard","slug":"failed-to-obtain-key-with-alias-keyalias-from-keystorefile","errorCode":null,"errorMessage":"Failed to obtain key with alias \"<keyAlias>\" from <keystoreFile>. Wrong password?","messagePattern":"Failed to obtain key with alias \"<keyAlias>\" from <keystoreFile>\\. Wrong password\\?","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"AndResGuard-core/src/main/java/apksigner/ApkSignerTool.java","lineNumber":760,"sourceCode":"                \"Key \\\"\" + keyAlias + \"\\\" password for \" + name\n            );\n            entryKey = getKeyStoreKey(ks, keyAlias, keyPasswords);\n          }\n        }\n\n        if (entryKey == null) {\n          throw new ParameterException(keystoreFile + \" entry \\\"\" + keyAlias + \"\\\" does not contain a key\");\n        } else if (!(entryKey instanceof PrivateKey)) {\n          throw new ParameterException(keystoreFile\n                                       + \" entry \\\"\"\n                                       + keyAlias\n                                       + \"\\\" does not contain a private\"\n                                       + \" key. It contains a key of algorithm: \"\n                                       + entryKey.getAlgorithm());\n        }\n        key = (PrivateKey) entryKey;\n      } catch (UnrecoverableKeyException e) {\n        throw new IOException(\"Failed to obtain key with alias \\\"\"\n                              + keyAlias\n                              + \"\\\" from \"\n                              + keystoreFile\n                              + \". Wrong password?\", e);\n      }\n      this.privateKey = key;\n      Certificate[] certChain = ks.getCertificateChain(keyAlias);\n      if ((certChain == null) || (certChain.length == 0)) {\n        throw new ParameterException(keystoreFile + \" entry \\\"\" + keyAlias + \"\\\" does not contain certificates\");\n      }\n      this.certs = new ArrayList<>(certChain.length);\n      for (Certificate cert : certChain) {\n        this.certs.add((X509Certificate) cert);\n      }\n    }\n\n    private void loadPrivateKeyAndCertsFromFiles(PasswordRetriever passwordRetriver) throws Exception {\n      if (keyFile == null) {","sourceCodeStart":742,"sourceCodeEnd":778,"githubUrl":"https://github.com/shwenzhang/AndResGuard/blob/e4df245d82f27d9a2d0dd108260a3510cbaba849/AndResGuard-core/src/main/java/apksigner/ApkSignerTool.java#L742-L778","documentation":"This IOException is thrown when KeyStore.getKey(alias, password) raises UnrecoverableKeyException while loading the signer's private key from the keystore. It means the keystore itself was opened, but the key under the given alias could not be decrypted/recovered with the supplied key password. The library appends 'Wrong password?' because that is by far the most common cause.","triggerScenarios":"Running apksigner-style signing (loadPrivateKeyAndCerts -> loadPrivateKeyAndCertsFromKeyStore) where --ks-key-alias names an existing alias but the provided key password does not match the one used when the key entry was created, or no key password is supplied for a keystore whose key entries use a different password than the keystore password.","commonSituations":"CI pipelines that set only the keystore password but the key entry was created with a distinct key password; keystores migrated between formats (JKS<->PKCS12) where key entry passwords were lost; copy-pasting the alias from a different keystore; typos or stale secrets rotated in the keystore but not in build config.","solutions":["Verify the key password with keytool: 'keytool -list -v -keystore <keystoreFile>' and re-enter the password used when generating the key entry.","If the key password differs from the keystore password, pass it explicitly via --ks-key-pass instead of relying on --ks-pass.","Re-import the key into a fresh keystore with a known key password if the original password is lost.","Confirm the alias is correct; a wrong alias pointing at a key with a different password can also trigger UnrecoverableKeyException."],"exampleFix":"// before\nsign({ ks: 'release.jks', ksPass: 'storepass', ksKeyAlias: 'release' })\n// after\nsign({ ks: 'release.jks', ksPass: 'storepass', ksKeyPass: 'keypass', ksKeyAlias: 'release' })","handlingStrategy":"try-catch","validationCode":"// Before signing, verify key recovery\nKeyStore ks = KeyStore.getInstance(new File(ksFile), ksPassword.toCharArray());\nKey key = ks.getKey(alias, keyPassword != null ? keyPassword.toCharArray() : ksPassword.toCharArray());\nif (key == null) throw new IllegalArgumentException(\"Alias not found: \" + alias);","typeGuard":"boolean isRecoverableKey(KeyStore ks, String alias, char[] pass) {\n  try { return ks.getKey(alias, pass) instanceof PrivateKey; }\n  catch (UnrecoverableKeyException e) { return false; }\n}","tryCatchPattern":"try {\n  signerParams.loadPrivateKeyAndCerts(passwordRetriever);\n} catch (IOException e) {\n  if (e.getMessage() != null && e.getMessage().contains(\"Wrong password?\")) {\n    // prompt user / re-fetch key password from secret manager and retry once\n  } else throw e;\n}","preventionTips":["Store keystore and key passwords separately in your secret manager and pass --ks-key-pass explicitly when they differ.","Test signing locally with keytool -list before running CI.","Keep one password policy for keystore + key entries in team keystores to avoid divergence."],"tags":["keystore","signing","wrong-password","android"],"backgroundTag":"wrong-key-password","analyzedSha":"e4df245d82f27d9a2d0dd108260a3510cbaba849","analyzedAt":"2026-09-12T17:49:07.798Z","contentChangedAt":"2026-09-12T17:49:07.798Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}