shwenzhang/AndResGuard · error · java.io.IOException
Can't Generate signed APK. Plz check your v1sign info is…
Error message
Can't Generate signed APK. Plz check your v1sign info is correct.
What it means
signApkV1 checks, after invoking jarsigner via signWithV1sign, whether the expected signed APK file exists on disk. If jarsigner failed (bad keystore, wrong passwords/alias, unsupported key) the output file is never created and this IOException is thrown. It is a generic post-condition check that hides the real jarsigner error, which is only printed to stderr earlier in the log.
Solutions
- Scroll up in the build log for the jarsigner stack trace/exit message printed before this IOException to find the root cause
- Verify the v1sign config values: signature file path exists, storePass, keyPass, and storeAlias are all correct
- Run jarsigner manually with the same arguments against the unsigned APK to reproduce the real error
- Ensure a JDK with jarsigner is installed and on PATH; also confirm the private key algorithm is DSA/RSA/EC
Example fix
// before (gradle config with wrong alias)
v1sign { storeFile file('old.keystore'); keyAlias 'release1' }
// after
v1sign { storeFile file('release.keystore'); storePassword '***'; keyAlias 'appkey'; keyPassword '***' } Defensive patterns
Strategy: validation
Validate before calling
File ks = new File(storeFilePath);
if (!ks.isFile()) throw new IllegalStateException("keystore not found: " + ks);
try {
KeyStore k = KeyStore.getInstance("JKS");
k.load(new FileInputStream(ks), storePass.toCharArray());
if (k.getKey(alias, keyPass.toCharArray()) == null)
throw new IllegalStateException("alias/password mismatch for " + alias);
} catch (Exception e) { throw new IllegalStateException("v1sign config invalid: " + e.getMessage(), e); } Try / catch
try {
andResGuard.build();
} catch (IOException e) {
if (e.getMessage().contains("Can't Generate signed APK")) {
// re-read the jarsigner output from the build log and surface the real cause
throw new IllegalStateException("v1 signing failed — check storePass/keyAlias/keyPass and jarsigner availability", e);
}
throw e;
} Prevention
- Run jarsigner manually with the same flags once before wiring CI
- Keep keystore passwords in gradle.properties/env vars, not hardcoded and rotated inconsistently
- Ensure a full JDK (not JRE-only image) is used in CI so jarsigner exists
- Read the full log, not just the last exception — the jarsigner cause is printed earlier
When it happens
Trigger: buildApkWithV1sign -> signApkV1 with config.mUseSignAPK=true when jarsigner exits non-zero: wrong storePass/keyPass/storeAlias, missing keystore file, jarsigner not on PATH, or the key-algorithm failure of error 50.
Common situations: Typoed signing config in gradle (storeFile/storePassword/keyAlias/keyPassword mismatch); keystore password changed after a rotation; running on CI where jarsigner (JDK) is absent; signing an EC key that jarsigner rejects.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- Can't Generate signed APK v2. Plz check your v2sign info is…
- Can not found any signed apk file
- private key is not a DSA or RSA key
- can not found the raw apk file to zipalign, path=
- Failed to determine APK's minimum supported platform…
AI-assisted analysis of shwenzhang/AndResGuard@e4df245d82 (2026-09-12).
Data as JSON: /api/errors/ff675f01b24b5069.
Report an issue: GitHub.
Appendix: source
Thrown at AndResGuard-core/src/main/java/com/tencent/mm/androlib/ResourceApkBuilder.java:204
throw new RuntimeException("private key is not a DSA or RSA key");
}
signatureAlgorithm = String.format("%swith%s", hash, keyAlgorithm);
return signatureAlgorithm;
}
private String formatHashAlgorithName(String hash) {
return hash.replace("-", "");
}
private void signApkV1(File unSignedApk, File signedApk) throws IOException, InterruptedException {
if (config.mUseSignAPK) {
System.out.printf("signing apk: %s\n", signedApk.getName());
if (signedApk.exists()) {
signedApk.delete();
}
signWithV1sign(unSignedApk, signedApk);
if (!signedApk.exists()) {
throw new IOException("Can't Generate signed APK. Plz check your v1sign info is correct.");
}
}
}
private void signApkV2V3(File unSignedApk, File signedApk, int minSDKVersion, InputParam.SignatureType signatureType) throws Exception {
if (config.mUseSignAPK) {
System.out.printf("signing apk: %s\n", signedApk.getName());
signWithV2V3Sign(unSignedApk, signedApk, minSDKVersion, signatureType);
if (!signedApk.exists()) {
throw new IOException("Can't Generate signed APK v2. Plz check your v2sign info is correct.");
}
}
}
private void signWithV2V3Sign(File unSignedApk, File signedApk, int minSDKVersion, InputParam.SignatureType signatureType) throws Exception {
String[] params = new String[] {
"sign",
"--ks",View on GitHub (pinned to e4df245d82)