{"record":{"id":"2e0dad6588e82ced","repo":"skylot/jadx","slug":"error-reading-library-chunk-at-offset-0x-x","errorCode":null,"errorMessage":"Error reading library chunk at offset 0x%x","messagePattern":"Error reading library chunk at offset 0x%x","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"jadx-core/src/main/java/jadx/core/xmlgen/ResTableBinaryParser.java","lineNumber":240,"sourceCode":"\t\t}\n\t}\n\n\tprivate void parseLibraryTypeChunk(long chunkStart) throws IOException {\n\t\tLOG.trace(\"parsing library type chunk starting at offset {}\", chunkStart);\n\t\tis.checkInt16(12, \"Unexpected header size\");\n\t\tint chunkSize = is.readInt32();\n\t\tlong expectedEndPos = chunkStart + chunkSize;\n\t\tint count = is.readInt32();\n\t\tfor (int i = 0; i < count; i++) {\n\t\t\tint packageId = is.readInt32();\n\t\t\tString packageName = is.readString16Fixed(128);\n\t\t\tLOG.info(\"Found resource shared library {}, pkgId: {}\", packageName, packageId);\n\t\t\tif (is.getPos() > expectedEndPos) {\n\t\t\t\tthrow new IOException(\"reading after chunk end\");\n\t\t\t}\n\t\t}\n\t\tif (is.getPos() != expectedEndPos) {\n\t\t\tthrow new IOException(String.format(\"Error reading library chunk at offset 0x%x\", chunkStart));\n\t\t}\n\t}\n\n\t/**\n\t * Parse an <code>ResTable_type</code> (except for the 2 bytes <code>uint16_t</code>\n\t * from <code>ResChunk_header</code>).\n\t *\n\t * @see <a href=\n\t *      \"https://github.com/aosp-mirror/platform_frameworks_base/blob/master/libs/androidfw/include/androidfw/ResourceTypes.h\"></a>ResourceTypes.h</a>\n\t */\n\tprivate void parseTypeChunk(long start, PackageChunk pkg) throws IOException {\n\t\t/* int headerSize = */\n\t\tis.readInt16();\n\t\t/* int size = */\n\t\tlong chunkSize = is.readUInt32();\n\t\tlong chunkEnd = start + chunkSize;\n\t\tis.mark((int) chunkSize);\n","sourceCodeStart":222,"sourceCodeEnd":258,"githubUrl":"https://github.com/skylot/jadx/blob/e738a26571d02919f01df40de93bc9a44dee4e18/jadx-core/src/main/java/jadx/core/xmlgen/ResTableBinaryParser.java#L222-L258","documentation":"After reading all library entries in a RES_TABLE_TYPE_LIBRARY chunk, the parser verifies the final stream position equals the expected chunk end. If the consumed bytes do not match chunkSize (e.g., count × entry-size < chunkSize), the chunk was not fully consumed, indicating a structural mismatch.","triggerScenarios":"parseLibraryTypeChunk finishes its loop and checks is.getPos() != expectedEndPos. Unlike the mid-loop check (247), this fires when fewer bytes were consumed than declared — the count field is too small, or chunkSize includes trailing data jadx does not parse.","commonSituations":"Malformed resources.arsc with inconsistent count/chunkSize. Newer library chunk format with additional trailing fields. Resource obfuscation tools.","solutions":["Re-extract resources from a clean APK","Upgrade jadx to the latest version","Report the APK to jadx maintainers","Use --no-res to bypass resource parsing"],"exampleFix":"// Skip resource decoding:\njadxArgs.setSkipResources(true);","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    resTableParser.decode(stream);\n} catch (IOException e) {\n    if (e.getMessage().contains(\"library chunk\")) {\n        LOG.warn(\"Library chunk size mismatch, skipping resources\", e);\n        jadxArgs.setSkipResources(true);\n    }\n}","preventionTips":["Cross-check with apktool for resource validity","Provide --no-res fallback","Report persistent issues to jadx"],"tags":["android","binary-parsing","validation","resource-table","corrupt-input"],"backgroundTag":null,"analyzedSha":"e738a26571d02919f01df40de93bc9a44dee4e18","analyzedAt":"2026-08-14T00:10:24.238Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}