shwenzhang/AndResGuard · error · RuntimeException

Neither KeyStore key alias nor private key file available

Error message

Neither KeyStore key alias nor private key file available

What it means

When deriving the v1 (JAR) signature file basename, the tool uses --v1-signer-name, then the keystore alias, then the key file name. If none of these is available it throws this RuntimeException — an internal invariant, since any loaded signer should have one.

Solutions

  1. Add --v1-signer-name <basename> explicitly
  2. Ensure --ks-key-alias is passed alongside --ks
  3. Or supply the key via --key so the file name can be used

Example fix

// before
apksigner sign --ks ks.jks --ks-pass env:KS app.apk
// after
apksigner sign --ks ks.jks --ks-key-alias release --ks-pass env:KS app.apk
Defensive patterns

Strategy: validation

Validate before calling

boolean hasAliasOrKey = Arrays.asList(args).contains("--ks-key-alias") || Arrays.asList(args).contains("--key");
if (!hasAliasOrKey) throw new IllegalArgumentException("Provide --ks-key-alias (or --key), or --v1-signer-name");

Try / catch

try { signCmd(args); } catch (RuntimeException e) { System.err.println(e.getMessage()); exit(2); }

Prevention

When it happens

Trigger: A signer loaded without keystoreKeyAlias and without keyFile (e.g. keystore path existed but alias resolution left both null), while --v1-signer-name was not provided.

Common situations: Custom/patched builds of the tool; providing certs in unusual ways; alias passed via a mechanism the tool didn't record (e.g. alias with different case handling).

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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

Appendix: source

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

          e.printStackTrace();
          System.exit(2);
          return;
        }
        String v1SigBasename;
        if (signer.v1SigFileBasename != null) {
          v1SigBasename = signer.v1SigFileBasename;
        } else if (signer.keystoreKeyAlias != null) {
          v1SigBasename = signer.keystoreKeyAlias;
        } else if (signer.keyFile != null) {
          String keyFileName = new File(signer.keyFile).getName();
          int delimiterIndex = keyFileName.indexOf('.');
          if (delimiterIndex == -1) {
            v1SigBasename = keyFileName;
          } else {
            v1SigBasename = keyFileName.substring(0, delimiterIndex);
          }
        } else {
          throw new RuntimeException("Neither KeyStore key alias nor private key file available");
        }
        ApkSigner.SignerConfig signerConfig = new ApkSigner.SignerConfig.Builder(v1SigBasename,
            signer.privateKey,
            signer.certs
        ).build();
        signerConfigs.add(signerConfig);
      }
    }

    if (outputApk == null) {
      outputApk = inputApk;
    }
    File tmpOutputApk;
    if (inputApk.getCanonicalPath().equals(outputApk.getCanonicalPath())) {
      tmpOutputApk = File.createTempFile("apksigner", ".apk");
      tmpOutputApk.deleteOnExit();
    } else {
      tmpOutputApk = outputApk;

View on GitHub (pinned to e4df245d82)