Tencent/tinker · error · DexException

Unexpected map value for 0x${type}

Error message

Unexpected map value for 0x${type}

What it means

Thrown by TableOfContents.readMap when a map_list entry's size or offset disagrees with what was already recorded — either a nonzero value read earlier from the header (stringIds/classDefs/etc. are populated from the header before the map is read) or a duplicate map item giving different numbers. The map and the header must be consistent.

Source

Thrown at third-party/aosp-dexutils/src/main/java/com/tencent/tinker/android/dex/TableOfContents.java:218

        classDefs.size = headerIn.readInt();
        classDefs.off = headerIn.readInt();
        dataSize = headerIn.readInt();
        dataOff = headerIn.readInt();
    }

    private void readMap(Dex.Section in) throws IOException {
        int mapSize = in.readInt();
        Section previous = null;
        for (int i = 0; i < mapSize; i++) {
            short type = in.readShort();
            in.readShort(); // unused
            Section section = getSection(type);
            int size = in.readInt();
            int offset = in.readInt();

            if ((section.size != 0 && section.size != size)
                    || (section.off != Section.UNDEF_OFFSET && section.off != offset)) {
                throw new DexException("Unexpected map value for 0x" + Integer.toHexString(type));
            }

            section.size = size;
            section.off = offset;

            if (previous != null && previous.off > section.off) {
                throw new DexException("Map is unsorted at " + previous + ", " + section);
            }

            previous = section;
        }

        header.off = 0;

        Arrays.sort(sections);

        // Skip header section, since its offset must be zero.
        for (int i = 1; i < sections.length; ++i) {

View on GitHub (pinned to 1b7ea02c23)

Solutions

  1. Regenerate the dex with d8/dx; both header and map are then written consistently.
  2. If you must patch dexes binary-wise, always update both the header fields and the map entries (and the checksum/signature) atomically.
  3. Validate inputs with `dexdump -f` which cross-checks header/map consistency and pinpoints the offending section type.
Defensive patterns

Strategy: try-catch

Validate before calling

null // full header/map cross-check requires parsing; cheap pre-check is `dexdump -f` in CI on every input dex

Try / catch

catch (DexException e) with 'Unexpected map value' -> reject input, require regeneration; record the type code from the message for triage

Prevention

When it happens

Trigger: Parsing a dex where the header's *_ids size/offset fields contradict the corresponding map entries, or the same section type appears twice in the map with different values — hallmarks of hand-edited or corrupt binaries, or buggy dex writers that fill the header and map independently.

Common situations: Post-processing tools (rewriters, hot-patch injectors) that update the map but not the header, or vice versa; dexes assembled by concatenating sections without reconciling both structures.

Related errors


AI-assisted analysis of Tencent/tinker@1b7ea02c23 (2026-08-14). Data as JSON: /api/errors/40ad532a1a0e42fe. Report an issue: GitHub.