Tencent/tinker · critical · TinkerRuntimeException
ShareSecurityCheck file %s, size %d verifyPatchMetaSignature
Error message
ShareSecurityCheck file %s, size %d verifyPatchMetaSignature fail
What it means
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.
Source
Thrown at tinker-android/tinker-android-loader-no-op/src/main/java/com/tencent/tinker/loader/shareutil/ShareSecurityCheck.java:130
final String name = jarEntry.getName();
if (name.startsWith("META-INF/")) {
continue;
}
//for faster, only check the meta.txt files
//we will check other files's md5 written in meta files
if (!name.endsWith(ShareConstants.META_SUFFIX)) {
continue;
}
metaContentMap.put(name, SharePatchFileUtil.loadDigestes(jarFile, jarEntry));
Certificate[] certs = jarEntry.getCertificates();
if (certs == null || !check(path, certs)) {
return false;
}
}
} catch (Exception e) {
throw new TinkerRuntimeException(
String.format("ShareSecurityCheck file %s, size %d verifyPatchMetaSignature fail", path.getAbsolutePath(), path.length()), e);
} finally {
try {
if (jarFile != null) {
jarFile.close();
}
} catch (IOException e) {
ShareTinkerLog.e(TAG, path.getAbsolutePath(), e);
}
}
return true;
}
// verify the signature of the Apk
private boolean check(File path, Certificate[] certs) {
if (certs.length > 0) {
for (int i = certs.length - 1; i >= 0; i--) {View on GitHub (pinned to 1b7ea02c23)
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.
Example fix
// before
TinkerInstaller.onReceiveUpgradePatch(context, patchPath); // dies inside verifyPatchMetaSignature
// after
String local = SharePatchFileUtil.getMD5(new File(patchPath));
if (!local.equalsIgnoreCase(expectedMd5FromServer)) {
ShareTinkerLog.e(TAG, "patch md5 mismatch, abort");
return;
}
TinkerInstaller.onReceiveUpgradePatch(context, patchPath); Defensive patterns
Strategy: validation
Validate before calling
File f = new File(patchPath);
if (!SharePatchFileUtil.isLegalFile(f)) { /* reject before security check */ }
String md5 = SharePatchFileUtil.getMD5(f);
if (!md5.equalsIgnoreCase(expectedMd5)) { /* reject corrupt download */ } Try / catch
catch TinkerRuntimeException containing 'verifyPatchMetaSignature fail' -> delete the patch file, redownload, and re-run the apply flow
Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- get public key md5 is null
- ShareSecurityCheck init public key fail
- Expected ${DEX_IN_JAR_NAME} in ${file}
- CRC mismatch
- Size mismatch
AI-assisted analysis of Tencent/tinker@1b7ea02c23 (2026-08-14).
Data as JSON: /api/errors/ea3470c179b48d31.
Report an issue: GitHub.