{"record":{"id":"ff675f01b24b5069","repo":"shwenzhang/AndResGuard","slug":"can-t-generate-signed-apk-plz-check-your-v1sign-info-is","errorCode":null,"errorMessage":"Can't Generate signed APK. Plz check your v1sign info is correct.","messagePattern":"Can't Generate signed APK\\. Plz check your v1sign info is correct\\.","errorType":"exception","errorClass":"java.io.IOException","httpStatus":null,"severity":"error","filePath":"AndResGuard-core/src/main/java/com/tencent/mm/androlib/ResourceApkBuilder.java","lineNumber":204,"sourceCode":"      throw new RuntimeException(\"private key is not a DSA or RSA key\");\n    }\n    signatureAlgorithm = String.format(\"%swith%s\", hash, keyAlgorithm);\n    return signatureAlgorithm;\n  }\n\n  private String formatHashAlgorithName(String hash) {\n    return hash.replace(\"-\", \"\");\n  }\n\n  private void signApkV1(File unSignedApk, File signedApk) throws IOException, InterruptedException {\n    if (config.mUseSignAPK) {\n      System.out.printf(\"signing apk: %s\\n\", signedApk.getName());\n      if (signedApk.exists()) {\n        signedApk.delete();\n      }\n      signWithV1sign(unSignedApk, signedApk);\n      if (!signedApk.exists()) {\n        throw new IOException(\"Can't Generate signed APK. Plz check your v1sign info is correct.\");\n      }\n    }\n  }\n\n  private void signApkV2V3(File unSignedApk, File signedApk, int minSDKVersion, InputParam.SignatureType signatureType) throws Exception {\n    if (config.mUseSignAPK) {\n      System.out.printf(\"signing apk: %s\\n\", signedApk.getName());\n      signWithV2V3Sign(unSignedApk, signedApk, minSDKVersion, signatureType);\n      if (!signedApk.exists()) {\n        throw new IOException(\"Can't Generate signed APK v2. Plz check your v2sign info is correct.\");\n      }\n    }\n  }\n\n  private void signWithV2V3Sign(File unSignedApk, File signedApk, int minSDKVersion, InputParam.SignatureType signatureType) throws Exception {\n    String[] params = new String[] {\n        \"sign\",\n        \"--ks\",","sourceCodeStart":186,"sourceCodeEnd":222,"githubUrl":"https://github.com/shwenzhang/AndResGuard/blob/e4df245d82f27d9a2d0dd108260a3510cbaba849/AndResGuard-core/src/main/java/com/tencent/mm/androlib/ResourceApkBuilder.java#L186-L222","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before (gradle config with wrong alias)\nv1sign { storeFile file('old.keystore'); keyAlias 'release1' }\n// after\nv1sign { storeFile file('release.keystore'); storePassword '***'; keyAlias 'appkey'; keyPassword '***' }","handlingStrategy":"validation","validationCode":"File ks = new File(storeFilePath);\nif (!ks.isFile()) throw new IllegalStateException(\"keystore not found: \" + ks);\ntry {\n  KeyStore k = KeyStore.getInstance(\"JKS\");\n  k.load(new FileInputStream(ks), storePass.toCharArray());\n  if (k.getKey(alias, keyPass.toCharArray()) == null)\n    throw new IllegalStateException(\"alias/password mismatch for \" + alias);\n} catch (Exception e) { throw new IllegalStateException(\"v1sign config invalid: \" + e.getMessage(), e); }","typeGuard":null,"tryCatchPattern":"try {\n  andResGuard.build();\n} catch (IOException e) {\n  if (e.getMessage().contains(\"Can't Generate signed APK\")) {\n    // re-read the jarsigner output from the build log and surface the real cause\n    throw new IllegalStateException(\"v1 signing failed — check storePass/keyAlias/keyPass and jarsigner availability\", e);\n  }\n  throw e;\n}","preventionTips":["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"],"tags":["java","signing","jarsigner","apk","io"],"backgroundTag":"file-not-found","analyzedSha":"e4df245d82f27d9a2d0dd108260a3510cbaba849","analyzedAt":"2026-09-12T17:49:07.798Z","contentChangedAt":"2026-09-12T17:49:07.798Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}