{"record":{"id":"ea3470c179b48d31","repo":"Tencent/tinker","slug":"sharesecuritycheck-file-s-size-d-verifypatchmet","errorCode":null,"errorMessage":"ShareSecurityCheck file %s, size %d verifyPatchMetaSignature fail","messagePattern":"ShareSecurityCheck file (.+?), size (.+?) verifyPatchMetaSignature fail","errorType":"exception","errorClass":"TinkerRuntimeException","httpStatus":null,"severity":"critical","filePath":"tinker-android/tinker-android-loader-no-op/src/main/java/com/tencent/tinker/loader/shareutil/ShareSecurityCheck.java","lineNumber":130,"sourceCode":"\n                final String name = jarEntry.getName();\n                if (name.startsWith(\"META-INF/\")) {\n                    continue;\n                }\n                //for faster, only check the meta.txt files\n                //we will check other files's md5 written in meta files\n                if (!name.endsWith(ShareConstants.META_SUFFIX)) {\n                    continue;\n                }\n                metaContentMap.put(name, SharePatchFileUtil.loadDigestes(jarFile, jarEntry));\n                Certificate[] certs = jarEntry.getCertificates();\n\n                if (certs == null || !check(path, certs)) {\n                    return false;\n                }\n            }\n        } catch (Exception e) {\n            throw new TinkerRuntimeException(\n                String.format(\"ShareSecurityCheck file %s, size %d verifyPatchMetaSignature fail\", path.getAbsolutePath(), path.length()), e);\n        } finally {\n            try {\n                if (jarFile != null) {\n                    jarFile.close();\n                }\n            } catch (IOException e) {\n                ShareTinkerLog.e(TAG, path.getAbsolutePath(), e);\n            }\n        }\n        return true;\n    }\n\n\n    // verify the signature of the Apk\n    private boolean check(File path, Certificate[] certs) {\n        if (certs.length > 0) {\n            for (int i = certs.length - 1; i >= 0; i--) {","sourceCodeStart":112,"sourceCodeEnd":148,"githubUrl":"https://github.com/Tencent/tinker/blob/1b7ea02c239840f563ea64fb5bd286eb98d4011e/tinker-android/tinker-android-loader-no-op/src/main/java/com/tencent/tinker/loader/shareutil/ShareSecurityCheck.java#L112-L148","documentation":"ShareSecurityCheck.verifyPatchMetaSignature opens the patch apk as a JarFile and, for every */meta-suffixed entry, loads digests and checks the entry's certificates against the app's own signature. Any exception during that iteration/verification is wrapped in TinkerRuntimeException('ShareSecurityCheck file <path>, size <len> verifyPatchMetaSignature fail'). It fires before any patch content is trusted.","triggerScenarios":"The patch zip being corrupt or unreadable as a JarFile; jarEntry.getCertificates() throwing while streaming a truncated entry; an IO failure mid-read of the patch file; malformed zip structures produced by repackaging tools that break JarFile's cert parsing.","commonSituations":"Patch signed with a different keystore than the app (manifest/cert streaming errors when tinker tries to verify); hotpatch packages rezipped by CDNs or packaging pipelines that strip v1 signature metadata; partial downloads; patches built with mismatched gradle-plugin/loader versions.","solutions":["Verify the patch file md5 matches what the server published before calling loadPatch; redownload on mismatch.","Ensure the patch is signed with the same certificate as the host app and that v1 (JAR) signing is enabled for the patch apk — JarFile certificate retrieval relies on it.","Rebuild the patch with a matching tinker build setup (no manual re-zip / re-compression afterwards).","Inspect the caused-by exception: ZipException means corrupt zip, IOException means read failure, other check() failures point to signature mismatch."],"exampleFix":"// before\nTinkerInstaller.onReceiveUpgradePatch(context, patchPath); // dies inside verifyPatchMetaSignature\n\n// after\nString local = SharePatchFileUtil.getMD5(new File(patchPath));\nif (!local.equalsIgnoreCase(expectedMd5FromServer)) {\n    ShareTinkerLog.e(TAG, \"patch md5 mismatch, abort\");\n    return;\n}\nTinkerInstaller.onReceiveUpgradePatch(context, patchPath);","handlingStrategy":"validation","validationCode":"File f = new File(patchPath);\nif (!SharePatchFileUtil.isLegalFile(f)) { /* reject before security check */ }\nString md5 = SharePatchFileUtil.getMD5(f);\nif (!md5.equalsIgnoreCase(expectedMd5)) { /* reject corrupt download */ }","typeGuard":null,"tryCatchPattern":"catch TinkerRuntimeException containing 'verifyPatchMetaSignature fail' -> delete the patch file, redownload, and re-run the apply flow","preventionTips":["Enable v1 (JAR) signing on patch apks; JarFile cert checks depend on it.","Sign the patch with the same keystore as the host app.","Verify whole-package md5 before calling loadPatch."],"tags":["security-check","signature","zip","patch-package"],"backgroundTag":null,"analyzedSha":"1b7ea02c239840f563ea64fb5bd286eb98d4011e","analyzedAt":"2026-08-14T15:16:52.110Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}