Tencent/matrix · error · DexDataException

Magic number is wrong -- are you sure this is a DEX file?

Error message

Magic number is wrong -- are you sure this is a DEX file?

What it means

DexData.load reads a .dex file and validates the 8-byte magic header ('dex\n' + version + '\0') via verifyMagic before parsing. A mismatch means the input is not a valid DEX file; it logs the message to stderr and throws DexDataException, aborting the dependency scan.

Solutions

  1. Verify the input file is an extracted, uncompressed classesN.dex (check first bytes with `xxd file | head` — should start with 'dex\n035' or similar).
  2. If given an APK, extract the dex first (unzip classes.dex) or use the library's APK-handling entry point instead.
  3. Disable/unpack packers (DexGuard, 360 jiagu, etc.) — encrypted dexes won't have a plain magic header.
  4. Rebuild/re-download the artifact; a corrupted or partially written dex also fails magic validation.

Example fix

// before
DexData dexData = new DexData(new RandomAccessFile(inputPath, "r"));
dexData.load();
// after
try (RandomAccessFile raf = new RandomAccessFile(inputPath, "r")) {
    byte[] magic = new byte[8];
    raf.readFully(magic);
    if (magic[0] != 'd' || magic[1] != 'e' || magic[2] != 'x') {
        throw new IllegalArgumentException(inputPath + " is not a plain dex (packed or wrong file?)");
    }
    raf.seek(0);
    DexData dexData = new DexData(raf);
    dexData.load();
}
Defensive patterns

Strategy: validation

Validate before calling

static boolean isDexFile(File f) throws IOException {
    try (RandomAccessFile raf = new RandomAccessFile(f, "r")) {
        byte[] magic = new byte[4];
        raf.readFully(magic);
        return magic[0]=='d' && magic[1]=='e' && magic[2]=='x' && magic[3]=='\n';
    }
}

Try / catch

try {
    dexData.load();
} catch (DexDataException e) {
    Log.w(TAG, inputPath + " is not a plain dex (packed or corrupt?), skipping");
}

Prevention

When it happens

Trigger: Calling DexData.load (→ parseHeaderItem) on a file that isn't a DEX — a .jar/.apk path passed where a classes.dex was expected, a compressed/obfuscated (e.g. DexGuard-encrypted) dex, a truncated download, or a text file mistakenly used as input.

Common situations: Pointing matrix-apm tooling at an APK instead of an extracted dex; build outputs processed before dex generation finished; packed/hardened apps whose dexes are encrypted at rest; corrupted artifacts from interrupted builds.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of Tencent/matrix@3b8293bd65 (2026-09-08). Data as JSON: /api/errors/77df4d8aeda62514. Report an issue: GitHub.

Appendix: source

Thrown at matrix/matrix-android/matrix-commons/src/main/java/com/android/dexdeps/DexData.java:91

                || Arrays.equals(magic, HeaderItem.DEX_FILE_MAGIC_v038)
                || Arrays.equals(magic, HeaderItem.DEX_FILE_MAGIC_v039)
                || Arrays.equals(magic, HeaderItem.DEX_FILE_MAGIC_v040);
    }

    /**
     * Parses the interesting bits out of the header.
     */
    void parseHeaderItem() throws IOException {
        mHeaderItem = new HeaderItem();

        seek(0);

        byte[] magic = new byte[8];
        readBytes(magic);
        if (!verifyMagic(magic)) {
            System.err.println("Magic number is wrong -- are you sure "
                    + "this is a DEX file?");
            throw new DexDataException();
        }

        /*
         * Read the endian tag, so we properly swap things as we read
         * them from here on.
         */
        seek(8 + 4 + 20 + 4 + 4);
        mHeaderItem.endianTag = readInt();
        if (mHeaderItem.endianTag == HeaderItem.ENDIAN_CONSTANT) {
            /* do nothing */
        } else if (mHeaderItem.endianTag == HeaderItem.REVERSE_ENDIAN_CONSTANT) {
            /* file is big-endian (!), reverse future reads */
            isBigEndian = true;
        } else {
            System.err.println("Endian constant has unexpected value "
                    + Integer.toHexString(mHeaderItem.endianTag));
            throw new DexDataException();
        }

View on GitHub (pinned to 3b8293bd65)