Tencent/tinker · error · TinkerRuntimeException

patch dex file md5 is mismatch, but path is null!!!!

Error message

patch dex file md5 is mismatch, but path is null!!!!

What it means

In the ERROR_LOAD_PATCH_VERSION_DEX_MD5_MISMATCH branch, TinkerLoadResult expects INTENT_PATCH_MISMATCH_DEX_PATH naming the dex whose MD5 no longer matches the patch metadata. A null path makes it impossible to report via onLoadFileMd5Mismatch, so Tinker throws. The underlying trigger is dex content on disk differing from the recorded checksum — the null-path throw is the secondary inconsistency.

Source

Thrown at tinker-android/tinker-android-lib/src/main/java/com/tencent/tinker/lib/tinker/TinkerLoadResult.java:274

                    ShareTinkerLog.e(TAG, "patch lib file not found:%s", libPath);
                    tinker.getLoadReporter().onLoadFileNotFound(new File(libPath),
                        ShareConstants.TYPE_LIBRARY, false);
                } else {
                    ShareTinkerLog.e(TAG, "patch lib file not found, but path is null!!!!");
                    throw new TinkerRuntimeException("patch lib file not found, but path is null!!!!");
                    // tinker.getLoadReporter().onLoadFileNotFound(null,
                    //     ShareConstants.TYPE_LIBRARY, false);
                }
                break;
            case ShareConstants.ERROR_LOAD_PATCH_VERSION_DEX_CLASSLOADER_NULL:
                ShareTinkerLog.e(TAG, "patch dex load fail, classloader is null");
                break;
            case ShareConstants.ERROR_LOAD_PATCH_VERSION_DEX_MD5_MISMATCH:
                String mismatchPath = ShareIntentUtil.getStringExtra(intentResult,
                    ShareIntentUtil.INTENT_PATCH_MISMATCH_DEX_PATH);
                if (mismatchPath == null) {
                    ShareTinkerLog.e(TAG, "patch dex file md5 is mismatch, but path is null!!!!");
                    throw new TinkerRuntimeException("patch dex file md5 is mismatch, but path is null!!!!");
                } else {
                    ShareTinkerLog.e(TAG, "patch dex file md5 is mismatch: %s", mismatchPath);
                    tinker.getLoadReporter().onLoadFileMd5Mismatch(new File(mismatchPath),
                        ShareConstants.TYPE_DEX);
                }
                break;
            case ShareConstants.ERROR_LOAD_PATCH_REWRITE_PATCH_INFO_FAIL:
                ShareTinkerLog.i(TAG, "rewrite patch info file corrupted");
                tinker.getLoadReporter().onLoadPatchInfoCorrupted(oldVersion, newVersion, patchInfoFile);
                break;
            case ShareConstants.ERROR_LOAD_PATCH_VERSION_RESOURCE_DIRECTORY_NOT_EXIST:
                if (patchVersionDirectory != null) {
                    ShareTinkerLog.e(TAG, "patch resource file directory not found:%s", resourceDirectory.getAbsolutePath());
                    tinker.getLoadReporter().onLoadFileNotFound(resourceDirectory,
                        ShareConstants.TYPE_RESOURCE, true);
                } else {
                    //should be not here
                    ShareTinkerLog.e(TAG, "patch resource file directory not found, warning why the path is null!!!!");

View on GitHub (pinned to 1b7ea02c23)

Solutions

  1. cleanPatch() to remove the tampered/corrupt patch and restore base behavior, then re-apply a freshly downloaded patch.
  2. Verify the downloaded patch file's md5 on the server side before handing it to TinkerInstaller.onReceiveUpgradePatch.
  3. Check device storage health if it recurs on the same devices.
  4. Align tinker component versions.
Defensive patterns

Strategy: validation

Validate before calling

// before handing a downloaded patch to tinker, verify whole-file md5
public static boolean verifyFileMd5(File patch, String expected) throws IOException {
    return expected != null && expected.equals(SharePatchFileUtil.getMD5(patch));
}

Try / catch

catch (TinkerRuntimeException e) {
    if (e.getMessage() != null && e.getMessage().contains("md5 is mismatch")) {
        Tinker.with(app).cleanPatch();
    } else throw e;
}

Prevention

When it happens

Trigger: Loader detects a dex file whose MD5 differs from the value in the patch's dex metadata and returns ERROR_LOAD_PATCH_VERSION_DEX_MD5_MISMATCH, but fails to attach INTENT_PATCH_MISMATCH_DEX_PATH.

Common situations: Disk corruption or truncation of a patch dex; anti-tampering software modifying dex files; hotpatch attempt after a partially-applied patch; version mismatch between components.

Related errors


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