Tencent/tinker · critical · TinkerRuntimeException
get public key md5 is null
Error message
get public key md5 is null
What it means
ShareSecurityCheck.init computes the MD5 of the host app's first APK signature block (PackageInfo.signatures[0]) via SharePatchFileUtil.getMD5. getMD5 returns null when the digest cannot be produced; here that null is treated as fatal and TinkerRuntimeException('get public key md5 is null') is thrown. Without the public-key md5, tinker cannot validate that patches are signed by the same key as the app.
Source
Thrown at tinker-android/tinker-android-loader-no-op/src/main/java/com/tencent/tinker/loader/shareutil/ShareSecurityCheck.java:170
}
} catch (Exception e) {
ShareTinkerLog.e(TAG, path.getAbsolutePath(), e);
}
}
}
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
- Reinstall the app normally (from Play/adb) so PackageManager returns standard signature data, then retry loading the patch.
- If reproducible on one device/ROM only, treat tinker as unsupported there: gate patch loading behind a device blacklist or capability check.
- Compute the expected md5 with the same code (SharePatchFileUtil.getMD5 on signatures[0].toByteArray()) in a debug build to see whether null is deterministic on that device.
- Upgrade tinker — newer builds use GET_SIGNING_CERTIFICATES paths on modern Android instead of the legacy GET_SIGNATURES flow.
Example fix
// before
mPublicKeyMd5 = SharePatchFileUtil.getMD5(packageInfo.signatures[0].toByteArray());
if (mPublicKeyMd5 == null) throw new TinkerRuntimeException("get public key md5 is null");
// after
byte[] sig = packageInfo.signatures[0].toByteArray();
mPublicKeyMd5 = SharePatchFileUtil.getMD5(sig);
if (mPublicKeyMd5 == null) {
MessageDigest md = null;
try { md = MessageDigest.getInstance("MD5"); } catch (NoSuchAlgorithmException ignored) { }
mPublicKeyMd5 = (md == null) ? null : toHex(md.digest(sig));
} Defensive patterns
Strategy: fallback
Validate before calling
Signature[] sigs = context.getPackageManager()
.getPackageInfo(context.getPackageName(), PackageManager.GET_SIGNATURES).signatures;
if (sigs == null || sigs.length == 0 || SharePatchFileUtil.getMD5(sigs[0].toByteArray()) == null) {
// signature identity unavailable: disable patch loading on this device
} Try / catch
catch TinkerRuntimeException 'get public key md5 is null' -> disable tinker for the session and report the device model
Prevention
- Probe signature-md5 availability at app startup before enabling patch loading.
- Blacklist devices/ROMs where the signature digest is unavailable.
- Keep tinker current for modern GET_SIGNING_CERTIFICATES handling.
When it happens
Trigger: getMD5 failing on the signature bytes (stream/digest IO failure, though rare); packageInfo.signatures being empty on exotic ROMs so [0] is not the issue here but getMD5 receives data it cannot digest; device-level crypto provider issues.
Common situations: Devices with broken MessageDigest/MemoryFile behavior; apps installed via unusual channels (enterprise stores, some work-profile containers) where PackageManager returns atypical signature data; extremely rare vendor crypto bugs.
Related errors
- ShareSecurityCheck init public key fail
- ShareSecurityCheck file %s, size %d verifyPatchMetaSignature
- ShareSecurityCheck file %s, size %d verifyPatchMetaSignature
- get public key md5 is null
- ShareSecurityCheck init public key fail
AI-assisted analysis of Tencent/tinker@1b7ea02c23 (2026-08-14).
Data as JSON: /api/errors/0d96df3c476f15af.
Report an issue: GitHub.