{"record":{"id":"7337ce32e25e78eb","repo":"skylot/jadx","slug":"failed-to-read-bytes-for-entry","errorCode":null,"errorMessage":"Failed to read bytes for entry: {}","messagePattern":"Failed to read bytes for entry: (.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"jadx-commons/jadx-zip/src/main/java/jadx/zip/fallback/FallbackZipParser.java","lineNumber":78,"sourceCode":"\t\t\treturn new ZipContent(this, list);\n\t\t} catch (Exception e) {\n\t\t\tthrow new FallbackException(\"Error opening zip file: \" + file.getAbsolutePath(), e);\n\t\t}\n\t}\n\n\tprivate boolean isValidEntry(IZipEntry zipEntry) {\n\t\tboolean validEntry = zipSecurity.isValidEntry(zipEntry);\n\t\tif (!validEntry) {\n\t\t\tLOG.warn(\"Zip entry '{}' is invalid and excluded from processing\", zipEntry);\n\t\t}\n\t\treturn validEntry;\n\t}\n\n\tpublic byte[] getBytes(FallbackZipEntry entry) {\n\t\ttry (InputStream is = getEntryStream(entry)) {\n\t\t\treturn is.readAllBytes();\n\t\t} catch (Exception e) {\n\t\t\tthrow new RuntimeException(\"Failed to read bytes for entry: \" + entry.getName(), e);\n\t\t}\n\t}\n\n\tpublic InputStream getInputStream(FallbackZipEntry entry) {\n\t\ttry {\n\t\t\treturn getEntryStream(entry);\n\t\t} catch (Exception e) {\n\t\t\tthrow new RuntimeException(\"Failed to open input stream for entry: \" + entry.getName(), e);\n\t\t}\n\t}\n\n\tprivate InputStream getEntryStream(FallbackZipEntry entry) throws IOException {\n\t\tInputStream entryStream = zipFile.getInputStream(entry.getZipEntry());\n\t\tInputStream stream;\n\t\tif (useLimitedDataStream) {\n\t\t\tstream = new LimitedInputStream(entryStream, entry.getUncompressedSize());\n\t\t} else {\n\t\t\tstream = entryStream;","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/skylot/jadx/blob/e738a26571d02919f01df40de93bc9a44dee4e18/jadx-commons/jadx-zip/src/main/java/jadx/zip/fallback/FallbackZipParser.java#L60-L96","documentation":"Thrown by the fallback zip parser (Java built-in ZipFile based) when fully reading an entry's decompressed bytes fails. getBytes() wraps the underlying InputStream in a LimitedInputStream and calls readAllBytes(); any IOException/DataFormatException/IllegalStateException from opening the stream, the read, or the size guard is caught and rethrown as a RuntimeException that names the offending entry. The original cause is attached so the real failure (CRC error, truncation, encryption) is inspectable via getCause().","triggerScenarios":"Calling IZipEntry.getBytes() / FallbackZipParser.getBytes() on a FallbackZipEntry whose underlying ZipFile.getInputStream() throws, or whose readAllBytes() hits an IOException, or whose LimitedInputStream trips the read-limit guard. This code path runs when the custom JadxZipParser could not handle the archive and jadx switched to the fallback parser.","commonSituations":"A corrupted or truncated APK/JAR/WAR where the central directory points at damaged compressed data; an entry that was partially written during an interrupted build; a crafted zip with a deliberately small declared uncompressed size; an encrypted entry the standard ZipFile cannot decrypt; disk I/O errors on the temp file holding the archive.","solutions":["Inspect getCause() on the thrown RuntimeException to identify whether it is CRC failure, truncation, the read-limit guard (LimitedInputStream), or a decrypt error.","If the cause is a read-limit or size mismatch, treat the archive as untrusted/suspect and re-acquire it from a trusted source.","If the cause is encryption, jadx does not support decrypting protected entries; supply an unencrypted archive or skip the entry.","Wrap the call in a try/catch and skip the failing entry so the rest of the archive still processes."],"exampleFix":"// before\nbyte[] data = entry.getBytes();\nprocess(data);\n\n// after\nbyte[] data;\ntry {\n    data = entry.getBytes();\n} catch (RuntimeException e) {\n    LOG.warn(\"Skipping unreadable entry {}: {}\", entry.getName(), e.getCause());\n    continue;\n}\nprocess(data);","handlingStrategy":"try-catch","validationCode":"// Pre-validate the entry is readable by checking the underlying zip is still open\n// and the entry is not encrypted. There is no cheap 'canRead' probe, so validate\n// what you can:\nif (zipEntry.isDirectory()) {\n    return; // directories have no bytes\n}","typeGuard":null,"tryCatchPattern":"try {\n    byte[] data = zipEntry.getBytes();\n} catch (RuntimeException e) {\n    Throwable cause = e.getCause(); // IOException, DataFormatException, IllegalStateException\n    LOG.warn(\"Skipping entry {}: {}\", zipEntry.getName(), cause);\n    continue;\n}","preventionTips":["Always inspect getCause() rather than the wrapper message to find the real failure.","Validate the archive integrity (CRC, size) before feeding untrusted zips to jadx.","Treat the fallback parser as best-effort: wrap per-entry reads in try/catch and skip bad entries."],"tags":["zip","io","fallback-parser","corrupted-archive"],"backgroundTag":null,"analyzedSha":"e738a26571d02919f01df40de93bc9a44dee4e18","analyzedAt":"2026-08-14T00:10:24.238Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}