pxb1988/dex2jar · error · IOException
The source file is not a .dex or .zip file
Error message
The source file is not a .dex or .zip file
What it means
MultiDexFileReader.open(byte[]) throws IOException as a final fallback when the input's first bytes match neither the 'dex' magic nor the 'PK' zip prefix, i.e. the byte array is not a dex file and not a zip container. The library auto-detects format from the magic bytes and has no handler for anything else.
Solutions
- Check the first bytes of your input (file/x magic) to confirm it is a dex or zip.
- If the content is gzip/other-compressed, decompress before calling open().
- If you got HTML/JSON from a failed HTTP download, fix the download (check URL, status code) and retry.
- For .odex/.vdex or native binaries, convert/deoptimize them to a real dex first.
Example fix
// before
BaseDexFileReader r = MultiDexFileReader.open(bytes);
// after
String magic = new String(bytes, 0, 3, StandardCharsets.ISO_8859_1);
if (!magic.startsWith("dex") && !magic.startsWith("PK")) {
throw new IllegalArgumentException("expected dex or zip, got magic=" + magic);
}
BaseDexFileReader r = MultiDexFileReader.open(bytes); Defensive patterns
Strategy: validation
Validate before calling
String magic = data.length >= 3 ? new String(data, 0, 3, StandardCharsets.ISO_8859_1) : "";
if (!magic.startsWith("dex") && !magic.startsWith("PK")) {
throw new IllegalArgumentException("expected dex or zip, got magic=" + magic);
} Type guard
static boolean isDexOrZip(byte[] d) {
return d != null && d.length >= 3 &&
(new String(d, 0, 3, StandardCharsets.ISO_8859_1).startsWith("dex") ||
new String(d, 0, 2, StandardCharsets.ISO_8859_1).equals("PK"));
} Try / catch
try {
BaseDexFileReader r = MultiDexFileReader.open(bytes);
} catch (IOException e) {
LOG.error("unsupported format: " + e.getMessage());
} Prevention
- Sniff magic bytes before passing binary data to dex tools
- Check HTTP status/content-type when downloading APKs (avoid saving HTML error pages)
- Decompress gzip streams before handing bytes to the reader
- Map file extensions (.odex/.vdex/.so) to the right tooling, not the dex reader
When it happens
Trigger: Calling MultiDexFileReader.open(bytes) on content starting with anything other than 'dex' or 'PK' — e.g. an ELF .so library, a binary XML/ARSB file, a gzip stream, or plain text/HTML from a failed download.
Common situations: Downloading an APK via a URL that returned an HTML error page; passing an .odex/.vdex or native library where classes.dex was intended; passing a gzip-compressed dex that was never gunzipped.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- File too small to be a dex/zip
- File too small to be a dex/zip
- the src file not a .dex or zip file
- Odex unsupported.
- Magic unsupported.
AI-assisted analysis of pxb1988/dex2jar@b5bda4fb49 (2026-09-08).
Data as JSON: /api/errors/d48df5c2579f192d.
Report an issue: GitHub.
Appendix: source
Thrown at dex-reader/src/main/java/com/googlecode/d2j/reader/MultiDexFileReader.java:58
try (ZipFile zipFile = new ZipFile(data)) {
for (ZipEntry e : zipFile.entries()) {
String entryName = e.getName();
if (entryName.startsWith("classes") && entryName.endsWith(".dex")) {
if (!dexFileReaders.containsKey(entryName)) { // only the first one
dexFileReaders.put(entryName, new DexFileReader(toByteArray(zipFile.getInputStream(e))));
}
}
}
}
if (dexFileReaders.size() == 0) {
throw new IOException("Can not find classes.dex in zip file");
} else if (dexFileReaders.size() == 1) {
return dexFileReaders.firstEntry().getValue();
} else {
return new MultiDexFileReader(dexFileReaders.values());
}
}
throw new IOException("The source file is not a .dex or .zip file");
}
void init() {
Set<String> classes = new HashSet<>();
for (DexFileReader reader : readers) {
List<String> classNames = reader.getClassNames();
for (int i = 0; i < classNames.size(); i++) {
String className = classNames.get(i);
if (classes.add(className)) {
items.add(new Item(i, reader, className));
}
}
}
}
@Override
public int getDexVersion() {
int max = DexConstants.DEX_035;View on GitHub (pinned to b5bda4fb49)