iBotPeaches/Apktool · critical · AndrolibException
Could not decode arsc file.
Error message
Could not decode arsc file.
What it means
Catch-all thrown by BinaryResourceParser.parse when an IOException (other than the structured empty/invalid-chunk checks) escapes while reading the resource table. The original IOException is chained as the cause. It almost always means the arsc is truncated or unreadable at the byte level.
Source
Thrown at brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/BinaryResourceParser.java:144
ResChunkPullParser parser = new ResChunkPullParser(mIn);
try {
if (!nextChunk(parser)) {
throw new AndrolibException("Input file is empty.");
}
if (parser.chunkType() != ResChunkHeader.RES_TABLE_TYPE) {
throw new AndrolibException("Unexpected chunk: " + parser.chunkName() + " (expected: RES_TABLE_TYPE)");
}
parseTable(parser);
Log.d(TAG, "End of chunks at 0x%08x", mIn.position());
// We can't use remaining() here, the length of the main stream is unknown.
if (mIn.available() > 0) {
Log.d(TAG, "Ignoring trailing data at 0x%08x.", mIn.position());
}
} catch (IOException ex) {
throw new AndrolibException("Could not decode arsc file.", ex);
}
}
public void reset() {
mIn = null;
mMissingEntrySpecs.clear();
mInvalidConfigs.clear();
mValueStringPool = null;
mPackageCount = 0;
mPackage = null;
mTypeIdOffset = 0;
mTypeStringPool = null;
mKeyStringPool = null;
mHasSparseEntries = false;
mHasCompactEntries = false;
if (mEntrySpecFlagsOffsets != null) {
mEntrySpecFlagsOffsets.clear();
}View on GitHub (pinned to 79b63384d7)
Solutions
- Read the chained cause — an EOFException-like failure means truncation, other IOExceptions point to the stream/disk.
- Re-download or re-extract the APK and verify its checksum before decoding.
- Validate the arsc length against the zip central directory entry size (`unzip -v app.apk`).
- If the file is intentionally patched/obfuscated, compare with the original from the store/device to see which chunk overruns.
Defensive patterns
Strategy: try-catch
Validate before calling
// fully materialize before parsing to rule out stream issues
byte[] data = Files.readAllBytes(arscPath);
if (data.length < 12) throw new IllegalArgumentException("arsc truncated"); Try / catch
try {
parser.parse(new ByteArrayInputStream(data));
} catch (AndrolibException e) {
if ("Could not decode arsc file.".equals(e.getMessage())) {
Throwable cause = e.getCause(); // EOF => truncation; other IOException => stream/disk
}
} Prevention
- Parse from byte arrays, not live streams.
- Verify artifact checksums after download.
- Compare arsc actual size against the zip central directory entry.
When it happens
Trigger: An IOException raised inside parseTable (e.g. EOF while reading a string pool, config, or entry) because the declared chunk sizes exceed the actual file length; or a genuine stream failure (closed stream, disk error) while parsing.
Common situations: Partially downloaded APKs; arsc truncated by a repack tool that rewrote sizes; reading from a network stream that dropped mid-parse; zip entry read failures.
Related errors
- Input file is empty.
- Unexpected chunk:
- Missing type string pool.
- Missing key string pool
- Config size < 8
AI-assisted analysis of iBotPeaches/Apktool@79b63384d7 (2026-08-14).
Data as JSON: /api/errors/f792ad4ba3f1d491.
Report an issue: GitHub.