Tencent/tinker · critical · TinkerRuntimeException
ShareSecurityCheck init public key fail
Error message
ShareSecurityCheck init public key fail
What it means
ShareSecurityCheck.init catches every exception from PackageManager.getPackageInfo / signature access / md5 computation and rethrows TinkerRuntimeException("ShareSecurityCheck init public key fail", e). The original cause tells the story: NameNotFoundException, null signatures array, or digest failure. Without the app's public key md5, Tinker refuses to verify patches.
Source
Thrown at tinker-android/tinker-android-loader/src/main/java/com/tencent/tinker/loader/shareutil/ShareSecurityCheck.java:173
}
}
}
return false;
}
@SuppressLint("PackageManagerGetSignatures")
private void init(Context context) {
ByteArrayInputStream stream = null;
try {
PackageManager pm = context.getPackageManager();
String packageName = context.getPackageName();
PackageInfo packageInfo = pm.getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
mPublicKeyMd5 = SharePatchFileUtil.getMD5(packageInfo.signatures[0].toByteArray());
if (mPublicKeyMd5 == null) {
throw new TinkerRuntimeException("get public key md5 is null");
}
} catch (Exception e) {
throw new TinkerRuntimeException("ShareSecurityCheck init public key fail", e);
} finally {
SharePatchFileUtil.closeQuietly(stream);
}
}
}
View on GitHub (pinned to 1b7ea02c23)
Solutions
- Inspect the cause: NameNotFoundException vs NullPointerException on signatures.
- Make sure the APK is release-signed and installed normally.
- Update Tinker to a version compatible with the target API level's signing APIs.
- Catch TinkerRuntimeException around TinkerInstaller.load / security check usage and report patch-load failure instead of crashing.
- Avoid triggering patch load from instrumented or mocked contexts.
Example fix
// before
TinkerInstaller.load(tinkerApplication);
// after
try {
TinkerInstaller.load(tinkerApplication);
} catch (TinkerRuntimeException e) {
ShareTinkerLog.e(TAG, "tinker init fail, disable patch", e);
TinkerInternals.killTinkerApplicationProcess();
} Defensive patterns
Strategy: try-catch
Validate before calling
try {
PackageInfo pi = context.getPackageManager()
.getPackageInfo(context.getPackageName(), PackageManager.GET_SIGNATURES);
if (pi.signatures == null || pi.signatures.length == 0) {
// signatures unavailable on this install: expect init to fail
}
} catch (PackageManager.NameNotFoundException e) {
// context/package mismatch: patching cannot be secured
} Try / catch
try {
TinkerInstaller.load(application);
} catch (TinkerRuntimeException e) {
Throwable cause = e.getCause(); // PM failure, null signatures, digest error
// disable tinker for this session, report to monitoring
} Prevention
- Use matching Tinker versions for the target API level (signature API changes on P+).
- Verify the app is signed and installed via normal channels before enabling patching.
- Wrap TinkerInstaller.load in a top-level guard so security-check failures never crash startup.
When it happens
Trigger: new ShareSecurityCheck(context) on devices/contexts where getPackageInfo with GET_SIGNATURES throws or packageInfo.signatures is null/empty — e.g. Android P+ deprecating GET_SIGNATURES without GET_SIGNING_CERTIFICATES handling, or unusual install contexts.
Common situations: Targeting newer Android versions where signature APIs changed; shared-user / system apps without standard signing metadata; test environments with unsigned builds; PM returning null signatures on some OEM ROMs.
Related errors
- ShareSecurityCheck file %s, size %d verifyPatchMetaSignature
- get public key md5 is null
- Filename contains NUL byte: ${Arrays.toString(nameBytes)}
- No entries
- libName or context is null!
AI-assisted analysis of Tencent/tinker@1b7ea02c23 (2026-08-14).
Data as JSON: /api/errors/e401b15088859246.
Report an issue: GitHub.