Tencent/tinker · critical · TinkerRuntimeException

checkDexInstall failed

Error message

checkDexInstall failed

What it means

SystemClassLoaderAdder.loadDexes injects the patch dex files into the app's ClassLoader (via NewClassLoaderInjector on SDK>=24 or injectDexesInternal), then runs checkDexInstall to verify the patch classes are actually loadable. If verification fails it uninstalls the patch dex and throws TinkerRuntimeException(CHECK_DEX_INSTALL_FAIL / 'checkDexInstall failed'). Injection succeeded but the loaded dex is unusable.

Source

Thrown at tinker-android/tinker-android-loader/src/main/java/com/tencent/tinker/loader/SystemClassLoaderAdder.java:73

                                    boolean isProtectedApp, boolean useDLC) throws Throwable {
        ShareTinkerLog.i(TAG, "installDexes dexOptDir: " + dexOptDir.getAbsolutePath() + ", dex size:" + files.size());

        if (!files.isEmpty()) {
            files = createSortedAdditionalPathEntries(files);
            ClassLoader classLoader = loader;
            if (Build.VERSION.SDK_INT >= 24 && !isProtectedApp) {
                classLoader = NewClassLoaderInjector.inject(application, loader, dexOptDir, useDLC, files);
            } else {
                injectDexesInternal(classLoader, files, dexOptDir);
            }
            //install done
            sPatchDexCount = files.size();
            ShareTinkerLog.i(TAG, "after loaded classloader: " + classLoader + ", dex size:" + sPatchDexCount);

            if (!checkDexInstall(classLoader)) {
                //reset patch dex
                SystemClassLoaderAdder.uninstallPatchDex(classLoader);
                throw new TinkerRuntimeException(ShareConstants.CHECK_DEX_INSTALL_FAIL);
            }
        }
    }

    static void injectDexesInternal(ClassLoader cl, List<File> dexFiles, File optimizeDir) throws Throwable {
        if (Build.VERSION.SDK_INT >= 23) {
            V23.install(cl, dexFiles, optimizeDir);
        } else if (Build.VERSION.SDK_INT >= 19) {
            V19.install(cl, dexFiles, optimizeDir);
        } else if (Build.VERSION.SDK_INT >= 14) {
            V14.install(cl, dexFiles, optimizeDir);
        } else {
            V4.install(cl, dexFiles, optimizeDir);
        }
    }

    public static void installApk(PathClassLoader loader, List<File> files) throws Throwable {
        if (!files.isEmpty()) {

View on GitHub (pinned to 1b7ea02c23)

Solutions

  1. Verify the patch was built against the exact same base apk and tinker toolchain; rebuild and re-sign the patch.
  2. Ensure the patch dex targets the same API/bytecode level and ABI as the running process (no 64-bit patch loaded into a 32-bit process).
  3. Check checkDexInstall's logs for the underlying ClassNotFoundException/verify error to identify which class failed, then fix that class in the patch.
  4. Upgrade tinker; loader fixes for specific Android versions (especially 8.x/9.xClassLoader injection) land regularly.

Example fix

// before
SystemClassLoaderAdder.loadDexes(loader, dexFiles, dexOptDir, false, false, isProtectedApp, false, ...);

// after
try {
    SystemClassLoaderAdder.loadDexes(loader, dexFiles, dexOptDir, false, false, isProtectedApp, false, ...);
} catch (TinkerRuntimeException e) {
    if (ShareConstants.CHECK_DEX_INSTALL_FAIL.equals(e.getMessage())) {
        ShareTinkerLog.e(TAG, "patch dex unusable, rolling back", e);
        Tinker.with(app).cleanPatch();
    } else {
        throw e;
    }
}
Defensive patterns

Strategy: try-catch

Try / catch

catch TinkerRuntimeException with message CHECK_DEX_INSTALL_FAIL -> the loader already uninstalled the patch dex; call cleanPatch() and report patch version as failed

Prevention

When it happens

Trigger: checkDexInstall failing to load a known patch class: dex file corrupt, wrong-endian/ISA dex, odex mismatch with the running runtime, or classes failing verification on-device; also NewClassLoaderInjector-created loader not exposing the patch classes.

Common situations: Patch dex built with an incompatible build-tools/sdk version; 32/64-bit mismatch between patch odex and process; vendor ROMs blocking dex loading; proguard/manifest differences between base and patch causing the checked class to be absent.

Related errors


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