iBotPeaches/Apktool · error · AndrolibException

Missing key string pool

Error message

Missing key string pool

What it means

parseType also requires the package's key (resource name) string pool before decoding entries, since each entry's key index must be resolved to a name. A RES_TABLE_TYPE chunk found before the RES_TABLE_TYPE_KEY string pool chunk triggers this.

Source

Thrown at brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/BinaryResourceParser.java:327

        mIn.skipShort(); // typesCount
        int entryCount = mIn.readInt();

        skipUnreadHeader(parser);

        if (mEntrySpecFlagsOffsets != null) {
            mEntrySpecFlagsOffsets.add(Pair.of(mIn.position(), entryCount));
        }
        mIn.skipBytes(entryCount * 4); // flags

        mPackage.addTypeSpec(id, mTypeStringPool.getString(id - 1));
    }

    private void parseType(ResChunkPullParser parser) throws AndrolibException, IOException {
        if (mTypeStringPool == null) {
            throw new AndrolibException("Missing type string pool.");
        }
        if (mKeyStringPool == null) {
            throw new AndrolibException("Missing key string pool");
        }

        // ResTable_type
        int id = mIn.readUnsignedByte() - mTypeIdOffset;
        int flags = mIn.readUnsignedByte();
        mIn.skipShort(); // reserved
        int entryCount = mIn.readInt();
        int entriesStart = mIn.readInt();
        ResConfig config = parseConfig();

        skipUnreadHeader(parser);

        // #3311 - Some older apps have no TYPE_SPEC chunks, but still define TYPE chunks.
        ResTypeSpec typeSpec;
        try {
            typeSpec = mPackage.getTypeSpec(id);
        } catch (UndefinedResObjectException ignored) {
            typeSpec = mPackage.addTypeSpec(id, mTypeStringPool.getString(id - 1));

View on GitHub (pinned to 79b63384d7)

Solutions

  1. Validate the arsc with aapt2; failure there confirms the file, not apktool, is at fault.
  2. Source an unobfuscated copy of the APK for decoding.
  3. When building arsc yourself, emit both type and key string pools immediately after the package header, before any type data.
  4. Attach the failing arsc to an apktool GitHub issue if it comes from a real-world app.
Defensive patterns

Strategy: try-catch

Try / catch

try {
    apkDecoder.decode(apk, out);
} catch (AndrolibException e) {
    if ("Missing key string pool".equals(e.getMessage())) {
        // key-name pool missing or out of order — malformed arsc
    }
}

Prevention

When it happens

Trigger: Malformed or deliberately obfuscated arsc where the key string pool chunk is missing or ordered after the type chunks within a package.

Common situations: Same family as [25]/[26]: packer-mangled resources.arsc, buggy resource optimizers, or fuzzed/corrupt artifacts. Frequently co-occurs with 'Missing type string pool.' because both pools live in the same header region of the package.

Related errors


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