shwenzhang/AndResGuard · error · ParameterException

entry " " does not contain a private key. It contains a key…

Error message

<keystoreFile> entry "<keyAlias>" does not contain a private key. It contains a key of algorithm: <entryKey.getAlgorithm()>

What it means

The entry's key was retrieved successfully but is not an instance of java.security.PrivateKey (e.g. it is a SecretKey or other Key type). APK signing requires an asymmetric private key, so apksigner throws this ParameterException and reports the key's actual algorithm.

Solutions

  1. Point --ks-key-alias at the asymmetric signing key entry (RSA/EC PrivateKeyEntry), per keytool -list -v output.
  2. If the store is JCEKS holding only secret keys, generate/import a proper signing keypair (keytool -genkeypair) and sign with that.
  3. Check --ks-type: use the type matching the file (PKCS12 for .p12/.pfx) so entries load with the intended provider.
  4. In code, verify entry instanceof PrivateKey and its algorithm (RSA/EC) before invoking the signer.

Example fix

// before (alias points at an AES secret key)
--ks-key-alias aes-key
// after
--ks-key-alias release  // RSA PrivateKeyEntry
Defensive patterns

Strategy: type-guard

Validate before calling

Key entryKey = ks.getKey(alias, keyPassword);
if (!(entryKey instanceof java.security.PrivateKey))
    throw new IllegalArgumentException("Alias '" + alias + "' holds a " + (entryKey == null ? "null" : entryKey.getAlgorithm()) + " key, not a PrivateKey; APK signing needs RSA/EC/DSA private key.");

Type guard

static boolean isSigningKey(java.security.Key k) {
    return k instanceof java.security.PrivateKey
        && ("RSA".equals(k.getAlgorithm()) || "EC".equals(k.getAlgorithm()) || "DSA".equals(k.getAlgorithm()));
}

Prevention

When it happens

Trigger: --ks-key-alias resolves to a secret-key entry (isKeyEntry true, getKey succeeds) whose Key fails the (entryKey instanceof PrivateKey) check — e.g. a symmetric AES key stored in the keystore, or a hardware-backed/software keystore type that returns non-PrivateKey Key implementations.

Common situations: Developers accidentally import a symmetric key (keytool -genseckey or JCEKS store) and try to sign with it; custom/sandboxed KeyStore providers returning wrapper Key objects not implementing PrivateKey; wrong --ks-type (JCEKS vs PKCS12) exposing secret-key entries.

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


AI-assisted analysis of shwenzhang/AndResGuard@e4df245d82 (2026-09-12). Data as JSON: /api/errors/22857bd329b7ddfb. Report an issue: GitHub.

Appendix: source

Thrown at AndResGuard-core/src/main/java/apksigner/ApkSignerTool.java:751

        } else {
          // Key password spec is not specified. This means we should assume that key
          // password is the same as the keystore password and that, if this assumption is
          // wrong, we should prompt for key password and retry loading the key using that
          // password.
          try {
            entryKey = getKeyStoreKey(ks, keyAlias, keystorePasswords);
          } catch (UnrecoverableKeyException expected) {
            List<char[]> keyPasswords = passwordRetriever.getPasswords(PasswordRetriever.SPEC_STDIN,
                "Key \"" + keyAlias + "\" password for " + name
            );
            entryKey = getKeyStoreKey(ks, keyAlias, keyPasswords);
          }
        }

        if (entryKey == null) {
          throw new ParameterException(keystoreFile + " entry \"" + keyAlias + "\" does not contain a key");
        } else if (!(entryKey instanceof PrivateKey)) {
          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");

View on GitHub (pinned to e4df245d82)