Tencent/tinker · error · TinkerRuntimeException
patch %s extract failed (%s).
Error message
patch %s extract failed (%s).
What it means
SoDiffPatchInternal's catch-all: any Throwable thrown while recovering native libraries from the patch (extracting old .so from the base APK, applying bsdiff or copying new/changed libraries, then MD5-verifying the result) is wrapped as 'patch lib extract failed'. Per-file MD5 verification failure is reported via onPatchTypeExtractFail and returns false; this exception indicates an unexpected Throwable escaped the so-recovery loop.
Source
Thrown at tinker-android/tinker-android-lib/src/main/java/com/tencent/tinker/lib/patch/SoDiffPatchInternal.java:210
} finally {
IOHelper.closeQuietly(oldStream);
IOHelper.closeQuietly(newStream);
}
//go go go bsdiff get the
if (!SharePatchFileUtil.verifyFileMd5(extractedFile, fileMd5)) {
ShareTinkerLog.w(TAG, "Failed to recover diff file " + extractedFile.getPath());
manager.getPatchReporter().onPatchTypeExtractFail(patchFile, extractedFile, info.name, type);
SharePatchFileUtil.safeDeleteFile(extractedFile);
return false;
}
ShareTinkerLog.w(TAG, "success recover bsdiff file: %s, use time: %d",
extractedFile.getPath(), (System.currentTimeMillis() - start));
}
}
} catch (Throwable e) {
throw new TinkerRuntimeException("patch " + ShareTinkerInternals.getTypeString(type) + " extract failed (" + e.getMessage() + ").", e);
} finally {
SharePatchFileUtil.closeZip(apk);
SharePatchFileUtil.closeZip(patch);
}
return true;
}
}
View on GitHub (pinned to 1b7ea02c23)
Solutions
- Generate the patch from the exact installed APK including the correct abi splits (use the same split/abi configuration when building the patch).
- Verify patch file MD5 before applying.
- Check free disk space and patch directory writability.
- If targeting new page-size devices, regenerate patches with an updated tinker/bsdiff toolchain that matches the .so layout.
- Inspect the wrapped cause via onPatchException.
Defensive patterns
Strategy: try-catch
Validate before calling
// Only distribute so patches for abis actually present in the installed APK
Set<String> supportedAbis = Build.SUPPORTED_ABIS_SET or splits config;
if (!serverPayload.patchAbis.containsAll(supportedAbisOfInstalledApk)) {
stripSoFromFlagsOrRefuse();
}
if (!SharePatchFileUtil.verifyFileMd5(new File(patchPath), serverPayload.patchMd5)) {
refuse("bad so patch");
} Try / catch
try {
TinkerInstaller.onReceiveUpgradePatch(context, patchPath);
} catch (TinkerRuntimeException e) {
reportPatchApplyFailure(e.getCause() != null ? e.getCause() : e);
} Prevention
- Build so patches from the exact installed APK including matching abi splits.
- Keep tinker gradle plugin and lib versions aligned; regenerate so patches after toolchain updates.
- Check free disk space before applying, so recovery materializes full .so files on disk.
When it happens
Trigger: Applying a so patch when: the old .so entry cannot be read from the base APK zip, the bsdiff stream for a library is malformed, output file creation under the patch lib directory fails (permissions/disk), or an abi-filtered APK lacks an expected library.
Common situations: Patch built for a different abi split or base APK than installed (split APKs with per-abi .so sets); devices with 16 KB page-size .so formats mismatching the patch's; disk full; patch generated with an incompatible tinker tool version.
Related errors
- patch %s extract failed (%s).
- Bad isa num: {}
- getCurrentInstructionSet fail:
- Unsupported abi:
- Corrupt by wrong patch file.
AI-assisted analysis of Tencent/tinker@1b7ea02c23 (2026-08-14).
Data as JSON: /api/errors/e403264714b4a116.
Report an issue: GitHub.