{"record":{"id":"f9d257160ddd9431","repo":"iBotPeaches/Apktool","slug":"error-while-reading-chunk-header","errorCode":null,"errorMessage":"Error while reading chunk header.","messagePattern":"Error while reading chunk header\\.","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"critical","filePath":"brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ResChunkPullParser.java","lineNumber":146,"sourceCode":"        try {\n            mChunkOffset = mIn.position();\n            ResChunkHeader chunkHeader = ResChunkHeader.read(mIn);\n\n            if (chunkHeader.headerSize < ResChunkHeader.SIZE\n                    || chunkHeader.size < chunkHeader.headerSize) {\n                throw new IOException(\n                    String.format(\"Invalid chunk header: type=0x%04x, headerSize=%s, size=%s\",\n                        chunkHeader.type, chunkHeader.headerSize, chunkHeader.size));\n            }\n\n            mChunkHeader = chunkHeader;\n            return true;\n        } catch (EOFException ignored) {\n            // End of chunks due to end of stream.\n            mChunkOffset = OFFSET_ENDED;\n            return false;\n        } catch (IOException ex) {\n            throw new IOException(\"Error while reading chunk header.\", ex);\n        }\n    }\n\n    public int skipChunk() throws IOException {\n        if (mChunkHeader == null) {\n            throw new IllegalStateException();\n        }\n        try {\n            long position = mIn.position();\n            long chunkEnd = chunkEnd();\n            if (position == chunkEnd) {\n                return 0;\n            }\n            if (position > chunkEnd) {\n                throw new IOException(\"Stream advanced past chunk end.\");\n            }\n            return mIn.skipBytes((int) (chunkEnd - position));\n        } catch (EOFException ignored) {","sourceCodeStart":128,"sourceCodeEnd":164,"githubUrl":"https://github.com/iBotPeaches/Apktool/blob/79b63384d7d7e22917e6ea8b453272da7012515b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ResChunkPullParser.java#L128-L164","documentation":"ResChunkPullParser wraps any non-EOF IOException raised while reading an 8-byte chunk header (malformed length fields causing overreads, stream failures, closed streams) in this generic message, chaining the original exception. It is the transport-level failure counterpart of the structural check at [38].","triggerScenarios":"The underlying BinaryDataInputStream throws while reading header fields — stream closed mid-parse, network/disk I/O error, or header values that force reads past the size limit set on the pull parser.","commonSituations":"Parsing from live network streams that drop; InputStream closed by another thread; truncated files where header reads cross EOF in a way not caught as plain EOFException; zip streams with inconsistent entry sizes.","solutions":["Inspect the chained cause for the exact I/O failure class.","Prefer parsing from a fully materialized byte array (ByteArrayInputStream) so transport errors are impossible during parse.","Verify the input is a complete, checksummed copy before parsing.","If the cause is overreading past a size limit, the file is malformed — treat as corruption per [38]."],"exampleFix":"// before\nparser.parse(socket.getInputStream()); // stream may drop mid-parse\n\n// after\nbyte[] data = socket.getInputStream().readAllBytes(); // complete first\nparser.parse(new ByteArrayInputStream(data));","handlingStrategy":"fallback","validationCode":"// materialize input fully so transport I/O cannot fail mid-parse\nbyte[] data = inputStream.readAllBytes();\nparser.parse(new ByteArrayInputStream(data));","typeGuard":null,"tryCatchPattern":"try {\n    parser.parse(new ByteArrayInputStream(data));\n} catch (IOException e) {\n    if (\"Error while reading chunk header.\".equals(e.getMessage())) {\n        Throwable cause = e.getCause(); // overread => malformed; other => stream issue\n    }\n}","preventionTips":["Parse from byte arrays instead of live/network streams.","Don't share or close InputStreams while a parser owns them.","Validate chunk sizes up front when parsing untrusted binaries."],"tags":["apktool","chunk-header","io","parsing","streaming"],"backgroundTag":null,"analyzedSha":"79b63384d7d7e22917e6ea8b453272da7012515b","analyzedAt":"2026-08-14T10:43:28.812Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}