{"record":{"id":"5b1214ab2c433f39","repo":"skylot/jadx","slug":"no-data-can-t-read-bytes","errorCode":null,"errorMessage":"No data, can't read {} bytes","messagePattern":"No data, can't read (.+?) bytes","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"jadx-core/src/main/java/jadx/core/xmlgen/ParserStream.java","lineNumber":84,"sourceCode":"\t\t}\n\t\tint[] arr = new int[count];\n\t\tfor (int i = 0; i < count; i++) {\n\t\t\tarr[i] = readInt32();\n\t\t}\n\t\treturn arr;\n\t}\n\n\tpublic byte[] readInt8Array(int count) throws IOException {\n\t\tif (count == 0) {\n\t\t\treturn EMPTY_BYTE_ARRAY;\n\t\t}\n\t\treadPos += count;\n\t\tbyte[] arr = new byte[count];\n\t\tint pos = input.read(arr, 0, count);\n\t\twhile (pos < count) {\n\t\t\tint read = input.read(arr, pos, count - pos);\n\t\t\tif (read == -1) {\n\t\t\t\tthrow new IOException(\"No data, can't read \" + count + \" bytes\");\n\t\t\t}\n\t\t\tpos += read;\n\t\t}\n\t\treturn arr;\n\t}\n\n\t@Override\n\tpublic long skip(long count) throws IOException {\n\t\treadPos += count;\n\t\tlong pos = input.skip(count);\n\t\twhile (pos < count) {\n\t\t\tlong skipped = input.skip(count - pos);\n\t\t\tif (skipped == 0) {\n\t\t\t\tthrow new IOException(\"No data, can't skip \" + count + \" bytes\");\n\t\t\t}\n\t\t\tpos += skipped;\n\t\t}\n\t\treturn pos;","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/skylot/jadx/blob/e738a26571d02919f01df40de93bc9a44dee4e18/jadx-core/src/main/java/jadx/core/xmlgen/ParserStream.java#L66-L102","documentation":"ParserStream.readInt8Array reads a fixed number of bytes from the underlying Android binary resource stream. If the input ends prematurely (InputStream.read returns -1) before all requested bytes are delivered, an IOException is thrown indicating the requested count could not be satisfied. This is a hard failure: truncated or corrupt binary data cannot be partially consumed.","triggerScenarios":"Called during parsing of Android resources.arsc, binary XML, or AXML files where a chunk header declares a field size but the stream has fewer bytes remaining. The read loop accumulates bytes via input.read(arr, pos, count - pos); if read returns -1 (EOF) on any iteration before pos reaches count, the exception fires.","commonSituations":"Truncated APK or resources.arsc file (interrupted download, incomplete unzip). Corrupt or obfuscated resource table where chunk sizes are deliberately mis-specified. Processing a non-APK/AXML file through the resource parser. Reading a file that is simultaneously being written or modified.","solutions":["Verify the input file is a complete, valid APK/AXML by re-downloading or re-extracting it","Inspect the file with aapt dump or apktool to confirm the resource table is intact","Open an issue with jadx attaching the problematic file if it loads fine in other tools","Upgrade jadx to the latest version — binary parser robustness improves over time"],"exampleFix":"// No caller-side code fix; the error indicates corrupt/truncated input.\n// Validate the file before passing it to jadx:\nZipFile apk = new ZipFile(file);\nif (apk.getEntry(\"resources.arsc\").getSize() <= 0) {\n    throw new IllegalArgumentException(\"resources.arsc is empty/truncated\");\n}","handlingStrategy":"try-catch","validationCode":"// Validate file completeness before parsing:\nlong expected = apkEntry.getSize();\nlong actual = Files.size(extractedFile);\nif (actual < expected) {\n    throw new IllegalArgumentException(\"Truncated resource file\");\n}","typeGuard":"// No type guard — IOException is checked at compile time\ntry {\n    parser.decode(stream);\n} catch (IOException e) { ... }","tryCatchPattern":"try {\n    resTableParser.decode(inputStream);\n} catch (IOException e) {\n    if (e.getMessage().contains(\"No data, can't read\")) {\n        LOG.warn(\"Truncated resource input, skipping resources\", e);\n        jadxArgs.setSkipResources(true);\n    } else {\n        throw e;\n    }\n}","preventionTips":["Always validate file integrity (size, CRC) before feeding to the parser","Use fresh extractions from the original APK rather than cached copies","Catch IOException around decode() and fall back to --no-res"],"tags":["android","binary-parsing","io","resource-table","corrupt-input"],"backgroundTag":null,"analyzedSha":"e738a26571d02919f01df40de93bc9a44dee4e18","analyzedAt":"2026-08-14T00:10:24.238Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}