Tencent/tinker · error · TinkerRuntimeException
patch ${type} extract failed (${message}).
Error message
patch ${type} extract failed (${message}). What it means
Thrown by ArkHotDiffPatchInternal when an IOException escapes while extracting ArkHot (ArkAPK hotfix) patch entries from the patch ZIP into the patch version directory. The raw IOException is wrapped in a TinkerRuntimeException whose message is prefixed with the patch type string ('ark hot' or similar). It signals an I/O-level failure in patch package extraction, not a checksum or format mismatch (those are reported via onPatchTypeExtractFail).
Source
Thrown at tinker-android/tinker-android-lib/src/main/java/com/tencent/tinker/lib/patch/ArkHotDiffPatchInternal.java:87
File extractedFile = new File(dir + info.name);
if (extractedFile.exists()) {
if (md5.equals(SharePatchFileUtil.getMD5(extractedFile))) {
continue;
} else {
extractedFile.delete();
}
} else {
extractedFile.getParentFile().mkdirs();
}
ZipEntry patchFileEntry = patch.getEntry(patchRealPath);
if (!extract(patch, patchFileEntry, extractedFile, md5, false)) {
manager.getPatchReporter().onPatchTypeExtractFail(patchFile, extractedFile, info.name, type);
return false;
}
}
} catch (IOException e) {
throw new TinkerRuntimeException("patch " + ShareTinkerInternals.getTypeString(type)
+ " extract failed (" + e.getMessage() + ").", e);
} finally {
SharePatchFileUtil.closeZip(patch);
}
return true;
}
private static boolean patchArkHotLibraryExtract(Context context, String patchVersionDirectory,
String meta, File patchFile) {
String dir = patchVersionDirectory + "/" + ShareConstants.ARKHOTFIX_PATH + "/";
arkPatchList.clear();
ShareArkHotDiffPatchInfo.parseDiffPatchInfo(meta, arkPatchList);
if (!extractArkHotLibrary(context, dir, patchFile, TYPE_ARKHOT_SO)) {
return false;
}View on GitHub (pinned to 1b7ea02c23)
Solutions
- Verify the downloaded patch file's MD5 against the value distributed by the server before calling TinkerInstaller.onReceiveUpgradePatch.
- Check available disk space and that the patch directory (context.getFilesDir()/tinker) is writable before applying.
- Re-download the patch and retry the apply; a truncated ZIP is the most frequent cause.
- Confirm the patch was built with the same base APK (same tinkerId) and with ArkHot patching enabled in the gradle plugin.
- If it persists, capture the wrapped IOException cause and report it via your PatchReporter implementation.
Example fix
// before
TinkerInstaller.onReceiveUpgradePatch(context, patchFile);
// after
String expectedMd5 = serverPayload.patchMd5;
if (!SharePatchFileUtil.verifyFileMd5(patchFile, expectedMd5)) {
// discard and re-download instead of applying a broken patch
SharePatchFileUtil.safeDeleteFile(patchFile);
return;
}
TinkerInstaller.onReceiveUpgradePatch(context, patchFile); Defensive patterns
Strategy: try-catch
Validate before calling
String md5 = serverPayload.patchMd5;
if (!SharePatchFileUtil.verifyFileMd5(new File(patchPath), md5)) {
SharePatchFileUtil.safeDeleteFile(new File(patchPath));
requestPatchReDownload();
return;
}
if (context.getCacheDir().getFreeSpace() < MIN_PATCH_SPACE) {
notifyUserStorageLow();
return;
} Try / catch
try {
TinkerInstaller.onReceiveUpgradePatch(context, patchPath);
} catch (TinkerRuntimeException e) {
// e.getCause() is the original IOException
reportPatchApplyFailure(e.getCause());
} Prevention
- Always verify the patch file MD5 against the server-published value before applying.
- Check free disk space in the tinker patch directory before starting an apply.
- Download patches atomically (temp file + rename) so truncated zips are never handed to tinker.
When it happens
Trigger: Calling the ArkHot patch apply path (patchArkHotLibraryExtract / extractValidFile with the ark hot patch type) when: the patch ZIP entry for the ark so/dex cannot be read (patch.getEntry returns a broken stream), the destination file under patchVersionDirectory/arkhot/ cannot be created (parent dirs unwritable, disk full), or the ZIP stream is closed mid-read.
Common situations: Patch file truncated by an interrupted download; device storage exhausted or /data/data quota hit; patch directory permission changed after a backup/restore; patch package generated with a mismatched ArkHot layout (built against a different base APK or non-Ark build).
Related errors
- patch %s extract failed (%s).
- No entries
- patch %s extract failed (%s).
- can't recognize zip dex format file:%s
- zipEntry is null when get from oldApk
AI-assisted analysis of Tencent/tinker@1b7ea02c23 (2026-08-14).
Data as JSON: /api/errors/90dbe621780fbf7f.
Report an issue: GitHub.