shwenzhang/AndResGuard · error · ParameterException

KeyStore (--ks) or private key file (--key) must be…

Error message

KeyStore (--ks) or private key file (--key) must be specified

What it means

If neither keystoreFile nor keyFile is set, loadPrivateKeyAndCerts has no credential source and throws this ParameterException. Signing requires credentials, so the tool fails fast at parameter validation rather than producing an unsigned or invalidly signed APK.

Solutions

  1. Add --ks <keystore path> (with --ks-key-alias and password options) for KeyStore signing.
  2. Or add --key <pk8/pem> --cert <x509.pem> for file-based signing.
  3. Verify the variable/secret that should contain the keystore path is actually set and non-empty.

Example fix

// before
apksigner sign --out app-signed.apk app.apk
// after
apksigner sign --ks release.jks --ks-key-alias mykey --out app-signed.apk app.apk
Defensive patterns

Strategy: validation

Validate before calling

// shell pre-check
if [ -z "$KS_ARG" ] && [ -z "$KEY_ARG" ]; then
  echo "ERROR: signing credentials missing; set --ks or --key/--cert" >&2; exit 1
fi

Prevention

When it happens

Trigger: Running apksigner sign without any of --ks, --key (and --cert); e.g. only --out and the APK are given.

Common situations: Forgetting the signing flags entirely; environment variable or property holding the keystore path is empty so the flag never gets populated; CI secret injection failed silently.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

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

             && (keyFile == null)
             && (certFile == null)
             && (v1SigFileBasename == null)
             && (privateKey == null)
             && (certs == null);
    }

    private void loadPrivateKeyAndCerts(PasswordRetriever passwordRetriever) throws Exception {
      if (keystoreFile != null) {
        if (keyFile != null) {
          throw new ParameterException("--ks and --key may not be specified at the same time");
        } else if (certFile != null) {
          throw new ParameterException("--ks and --cert may not be specified at the same time");
        }
        loadPrivateKeyAndCertsFromKeyStore(passwordRetriever);
      } else if (keyFile != null) {
        loadPrivateKeyAndCertsFromFiles(passwordRetriever);
      } else {
        throw new ParameterException("KeyStore (--ks) or private key file (--key) must be specified");
      }
    }

    private void loadPrivateKeyAndCertsFromKeyStore(PasswordRetriever passwordRetriever) throws Exception {
      if (keystoreFile == null) {
        throw new ParameterException("KeyStore (--ks) must be specified");
      }

      // 1. Obtain a KeyStore implementation
      String ksType = (keystoreType != null) ? keystoreType : KeyStore.getDefaultType();
      KeyStore ks;
      if (keystoreProviderName != null) {
        // Use a named Provider (assumes the provider is already installed)
        ks = KeyStore.getInstance(ksType, keystoreProviderName);
      } else if (keystoreProviderClass != null) {
        // Use a new Provider instance (does not require the provider to be installed)
        Class<?> ksProviderClass = Class.forName(keystoreProviderClass);
        if (!Provider.class.isAssignableFrom(ksProviderClass)) {

View on GitHub (pinned to e4df245d82)