Tencent/tinker · critical · TinkerRuntimeException

ShareSecurityCheck init public key fail

Error message

ShareSecurityCheck init public key fail

What it means

ShareSecurityCheck.init wraps its whole body: any exception while fetching PackageManager, calling getPackageInfo with GET_SIGNATURES, or computing the signature md5 is caught and rethrown as TinkerRuntimeException('ShareSecurityCheck init public key fail'). This is the outer guard around error 174 — the app's identity could not be established, so no patch can be trusted.

Source

Thrown at tinker-android/tinker-android-loader-no-op/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

  1. Read the caused-by: NameNotFoundException means wrong package context, AIOOBE means empty signatures, TinkerRuntimeException('get public key md5 is null') means issue 174.
  2. Ensure tinker initialization runs in the main process with the application's real Context (not a backup/instrumentation context).
  3. On affected devices, disable patch loading (TinkerInstaller/disable flags) rather than crashing — identity checks failing is unrecoverable in-process.
  4. Upgrade tinker for modern signature APIs (GET_SIGNING_CERTIFICATES) and hardened init.

Example fix

// before
ShareSecurityCheck check = new ShareSecurityCheck(context); // throws TinkerRuntimeException from init

// after
ShareSecurityCheck check;
try {
    check = new ShareSecurityCheck(context);
} catch (TinkerRuntimeException e) {
    ShareTinkerLog.e(TAG, "security check unavailable on this device, disable tinker", e);
    TinkerInternals.disableTinkerInternals(context); // or set your own disable flag
    return;
}
Defensive patterns

Strategy: try-catch

Validate before calling

try {
    context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_SIGNATURES);
} catch (Exception e) {
    // PackageManager unhealthy: skip patch initialization this session
}

Try / catch

catch TinkerRuntimeException from ShareSecurityCheck construction -> log cause, disable tinker, continue app without hotpatch

Prevention

When it happens

Trigger: context.getPackageManager()/getPackageInfo throwing (NameNotFoundException, dead PackageManager transaction in a bad process state); packageInfo.signatures empty on rare ROMs making signatures[0] throw ArrayIndexOutOfBoundsException; the md5-null TinkerRuntimeException from error 174 itself landing in this catch.

Common situations: Instant-run-style or instrumented processes where the package context is odd; apps running inside work profiles/containers; heavy task-killer ROMs killing PackageManager binder calls; the underlying md5-null failure (174).

Related errors


AI-assisted analysis of Tencent/tinker@1b7ea02c23 (2026-08-14). Data as JSON: /api/errors/9b8ead6ae0689a39. Report an issue: GitHub.