shwenzhang/AndResGuard · error · ParameterException
entry " " does not contain certificates
Error message
<keystoreFile> entry "<keyAlias>" does not contain certificates
What it means
This ParameterException is thrown after the private key is recovered successfully when KeyStore.getCertificateChain(keyAlias) returns null or an empty array. A valid signing key entry must carry the certificate chain needed to build the APK signature; an alias without certificates cannot be used to sign.
Solutions
- Inspect the entry with 'keytool -list -v -keystore <keystoreFile> -alias <keyAlias>' and confirm it is a PrivateKeyEntry with a certificate chain.
- Re-generate the key with its certificate: 'keytool -genkeypair -alias <keyAlias> ...' so the entry includes the chain.
- If the key was imported without a cert, create/import the matching certificate: 'keytool -importcert -alias <keyAlias> -file cert.pem'.
- Double-check --ks-key-alias spelling; a similar alias may exist without certificates.
Example fix
// before: bare key import keytool -importkeystore ... // key entry without certificate // after certtool --self-sign && keytool -importcert -alias release -file release.crt -keystore release.jks
Defensive patterns
Strategy: validation
Validate before calling
KeyStore ks = KeyStore.getInstance(new File(ksFile), ksPassword.toCharArray());
java.security.cert.Certificate[] chain = ks.getCertificateChain(alias);
Key key = ks.getKey(alias, keyPass.toCharArray());
if (key instanceof PrivateKey && (chain == null || chain.length == 0)) {
throw new IllegalStateException("Entry " + alias + " has a private key but no certificate chain; re-export with its cert.");
} Type guard
boolean isSignableEntry(KeyStore ks, String alias, char[] keyPass) throws Exception {
java.security.cert.Certificate[] c = ks.getCertificateChain(alias);
return ks.getKey(alias, keyPass) instanceof PrivateKey && c != null && c.length > 0;
} Try / catch
try {
signerParams.loadPrivateKeyAndCerts(passwordRetriever);
} catch (ParameterException e) {
if (e.getMessage() != null && e.getMessage().endsWith("does not contain certificates")) {
throw new IllegalStateException("Keystore entry lacks certificate chain - re-create with keytool -genkeypair", e);
} throw e;
} Prevention
- Always create signing keys with keytool -genkeypair so the certificate chain is embedded in the entry.
- Never import a bare private key into a keystore without its matching certificate.
- Run 'keytool -list -v' in CI as a pre-flight check for PrivateKeyEntry + chain length.
When it happens
Trigger: loadPrivateKeyAndCertsFromKeyStore resolves the private key for --ks-key-alias, but the keystore entry under that alias holds only a raw key (e.g. a key imported without its certificate) or the alias actually points to a trusted-certificate-only entry with no private key chain.
Common situations: Importing a bare .key/PKCS#8 file into a keystore without 'keytool -importcert' for its certificate; aliases pointing to TrustedCertificateEntry rather than PrivateKeyEntry; corrupted or partially built keystores in CI caches.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- Failed to obtain key with alias
- Can't get private key, please check if storepass storealias…
- the signature file do not exit. raw path=
- No keystore passwords
- No key passwords
AI-assisted analysis of shwenzhang/AndResGuard@e4df245d82 (2026-09-12).
Data as JSON: /api/errors/d7f80462100017e0.
Report an issue: GitHub.
Appendix: source
Thrown at AndResGuard-core/src/main/java/apksigner/ApkSignerTool.java:769
throw new ParameterException(keystoreFile
+ " entry \""
+ keyAlias
+ "\" does not contain a private"
+ " key. It contains a key of algorithm: "
+ entryKey.getAlgorithm());
}
key = (PrivateKey) entryKey;
} catch (UnrecoverableKeyException e) {
throw new IOException("Failed to obtain key with alias \""
+ keyAlias
+ "\" from "
+ keystoreFile
+ ". Wrong password?", e);
}
this.privateKey = key;
Certificate[] certChain = ks.getCertificateChain(keyAlias);
if ((certChain == null) || (certChain.length == 0)) {
throw new ParameterException(keystoreFile + " entry \"" + keyAlias + "\" does not contain certificates");
}
this.certs = new ArrayList<>(certChain.length);
for (Certificate cert : certChain) {
this.certs.add((X509Certificate) cert);
}
}
private void loadPrivateKeyAndCertsFromFiles(PasswordRetriever passwordRetriver) throws Exception {
if (keyFile == null) {
throw new ParameterException("Private key file (--key) must be specified");
}
if (certFile == null) {
throw new ParameterException("Certificate file (--cert) must be specified");
}
byte[] privateKeyBlob = readFully(new File(keyFile));
PKCS8EncodedKeySpec keySpec;
// Potentially encrypted key blobView on GitHub (pinned to e4df245d82)