iBotPeaches/Apktool · critical · IOException

Unexpected chunk:

Error message

Unexpected chunk: 

What it means

BinaryXmlResourceParser requires the first chunk of its input to be RES_XML_TYPE (0x0003). Any other leading chunk type throws this error, naming the offending chunk — the usual meaning is 'this file is not compiled binary XML'.

Source

Thrown at brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/BinaryXmlResourceParser.java:119

    public void setInput(Reader in) throws XmlPullParserException {
        throw new XmlPullParserException(NOT_SUPPORTED);
    }

    @Override
    public void setInput(InputStream inputStream, String inputEncoding) throws XmlPullParserException {
        if (inputEncoding != null) {
            throw new XmlPullParserException(NOT_SUPPORTED);
        }

        reset();
        mIn = new BinaryDataInputStream(new BufferedInputStream(inputStream));
        mParser = new ResChunkPullParser(mIn);
        try {
            if (!nextChunk()) {
                throw new IOException("Input file is empty.");
            }
            if (mParser.chunkType() != ResChunkHeader.RES_XML_TYPE) {
                throw new IOException("Unexpected chunk: " + mParser.chunkName() + " (expected: RES_XML_TYPE)");
            }
        } catch (IOException ex) {
            mIn = null;
            mParser = null;
            throw new XmlPullParserException("Could not initialize parser.", this, ex);
        }

        mParser = new ResChunkPullParser(mIn, mParser.dataSize());
    }

    @Override
    public String getInputEncoding() {
        return null;
    }

    @Override
    public void defineEntityReplacementText(String entityName, String replacementText) throws XmlPullParserException {
        throw new XmlPullParserException(NOT_SUPPORTED);

View on GitHub (pinned to 79b63384d7)

Solutions

  1. Check the first two bytes: 0x0003 = binary XML, 0x0002 = resource table, '<' (0x3C) = plain text XML.
  2. If the file is plain text XML, parse it with a standard XmlPullParser instead — it never needed the binary parser.
  3. If it should be AXML but isn't, the APK build/extract step is broken — recompile with aapt2 or re-extract.
  4. For plain XML inside an APK from a non-standard packager, pre-detect the magic and route to the right parser.

Example fix

// before
parser.setInput(in, null); // throws if `in` is plain-text XML

// after
PushbackInputStream pb = new PushbackInputStream(in, 2);
int b0 = pb.read(), b1 = pb.read();
if (b0 == 0x03 && b1 == 0x00) {
    pb.unread(b1); pb.unread(b0);
    binParser.setInput(pb, null);
} else {
    pb.unread(b1); pb.unread(b0);
    textParser.setInput(pb, null); // plain-text XML path
}
Defensive patterns

Strategy: validation

Validate before calling

byte[] magic = new byte[2];
try (InputStream s = new FileInputStream(xmlFile)) { s.read(magic); }
boolean isBinaryXml = (magic[0] & 0xFF) == 0x03 && magic[1] == 0x00;
boolean isPlainText = magic[0] == '<';
if (!isBinaryXml) {
    // route to a standard text XmlPullParser if isPlainText, else reject
}

Try / catch

try {
    binParser.setInput(in, null);
} catch (XmlPullParserException e) {
    if (String.valueOf(e.getCause()).contains("Unexpected chunk")) {
        // wrong parser for this file — check magic and reroute
    }
}

Prevention

When it happens

Trigger: Feeding the AXML parser a plain-text XML file (not compiled), an arsc (starts with 0x0002), or any non-AXML binary. Also fires on AXML files whose header was corrupted.

Common situations: Parsing XML that was never compiled with aapt/aapt2 (source res XML); mixed-up streams in extraction code; tools that store plain XML in APKs (some non-standard build chains); hex-corrupted manifest files.

Related errors


AI-assisted analysis of iBotPeaches/Apktool@79b63384d7 (2026-08-14). Data as JSON: /api/errors/ce623fcbc50c8f08. Report an issue: GitHub.