{"record":{"id":"77df4d8aeda62514","repo":"Tencent/matrix","slug":"magic-number-is-wrong-are-you-sure-this-is-a-de","errorCode":null,"errorMessage":"Magic number is wrong -- are you sure this is a DEX file?","messagePattern":"Magic number is wrong -- are you sure this is a DEX file\\?","errorType":"console","errorClass":"DexDataException","httpStatus":null,"severity":"error","filePath":"matrix/matrix-android/matrix-commons/src/main/java/com/android/dexdeps/DexData.java","lineNumber":91,"sourceCode":"                || Arrays.equals(magic, HeaderItem.DEX_FILE_MAGIC_v038)\n                || Arrays.equals(magic, HeaderItem.DEX_FILE_MAGIC_v039)\n                || Arrays.equals(magic, HeaderItem.DEX_FILE_MAGIC_v040);\n    }\n\n    /**\n     * Parses the interesting bits out of the header.\n     */\n    void parseHeaderItem() throws IOException {\n        mHeaderItem = new HeaderItem();\n\n        seek(0);\n\n        byte[] magic = new byte[8];\n        readBytes(magic);\n        if (!verifyMagic(magic)) {\n            System.err.println(\"Magic number is wrong -- are you sure \"\n                    + \"this is a DEX file?\");\n            throw new DexDataException();\n        }\n\n        /*\n         * Read the endian tag, so we properly swap things as we read\n         * them from here on.\n         */\n        seek(8 + 4 + 20 + 4 + 4);\n        mHeaderItem.endianTag = readInt();\n        if (mHeaderItem.endianTag == HeaderItem.ENDIAN_CONSTANT) {\n            /* do nothing */\n        } else if (mHeaderItem.endianTag == HeaderItem.REVERSE_ENDIAN_CONSTANT) {\n            /* file is big-endian (!), reverse future reads */\n            isBigEndian = true;\n        } else {\n            System.err.println(\"Endian constant has unexpected value \"\n                    + Integer.toHexString(mHeaderItem.endianTag));\n            throw new DexDataException();\n        }","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/Tencent/matrix/blob/3b8293bd65d47eeea7caf1f32a3a5d4d5eab60e7/matrix/matrix-android/matrix-commons/src/main/java/com/android/dexdeps/DexData.java#L73-L109","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Verify the input file is an extracted, uncompressed classesN.dex (check first bytes with `xxd file | head` — should start with 'dex\\n035' or similar).","If given an APK, extract the dex first (unzip classes.dex) or use the library's APK-handling entry point instead.","Disable/unpack packers (DexGuard, 360 jiagu, etc.) — encrypted dexes won't have a plain magic header.","Rebuild/re-download the artifact; a corrupted or partially written dex also fails magic validation."],"exampleFix":"// before\nDexData dexData = new DexData(new RandomAccessFile(inputPath, \"r\"));\ndexData.load();\n// after\ntry (RandomAccessFile raf = new RandomAccessFile(inputPath, \"r\")) {\n    byte[] magic = new byte[8];\n    raf.readFully(magic);\n    if (magic[0] != 'd' || magic[1] != 'e' || magic[2] != 'x') {\n        throw new IllegalArgumentException(inputPath + \" is not a plain dex (packed or wrong file?)\");\n    }\n    raf.seek(0);\n    DexData dexData = new DexData(raf);\n    dexData.load();\n}","handlingStrategy":"validation","validationCode":"static boolean isDexFile(File f) throws IOException {\n    try (RandomAccessFile raf = new RandomAccessFile(f, \"r\")) {\n        byte[] magic = new byte[4];\n        raf.readFully(magic);\n        return magic[0]=='d' && magic[1]=='e' && magic[2]=='x' && magic[3]=='\\n';\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    dexData.load();\n} catch (DexDataException e) {\n    Log.w(TAG, inputPath + \" is not a plain dex (packed or corrupt?), skipping\");\n}","preventionTips":["Only feed extracted classesN.dex files, not APKs or jars.","Handle packed/hardened apps (DexGuard, jiagu) — their dexes are encrypted and will fail magic validation.","Validate the first bytes ('dex\\n') before loading.","Rebuild corrupted artifacts from interrupted builds."],"tags":["dex","file-format","static-analysis","android"],"backgroundTag":"invalid-argument-value","analyzedSha":"3b8293bd65d47eeea7caf1f32a3a5d4d5eab60e7","analyzedAt":"2026-09-08T08:01:39.722Z","contentChangedAt":"2026-09-08T08:01:39.722Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}