pxb1988/dex2jar · error · IOException
Can not find classes.dex in zip file
Error message
Can not find classes.dex in zip file
What it means
MultiDexFileReader.open(byte[]) throws IOException when the input is a valid ZIP (PK prefix) but no .dex entries were found inside it, so dexFileReaders ends up empty. The library expects APK/zip inputs to contain at least one classes*.dex entry.
Solutions
- Confirm the input is a real APK containing classes.dex (unzip -l).
- If entries use different names/casing, rename them to classes.dex / classes2.dex or unpack and rebuild the APK.
- If the APK is protected/packed, dump the runtime dex files first (e.g. with a unpacker) and pass those dex bytes instead.
- If you intended a raw dex, pass the .dex bytes directly instead of the zip.
Example fix
// before BaseDexFileReader r = MultiDexFileReader.open(zipBytes); // after byte[] dexBytes = ZipUtil.readDex(zipBytes); // throws its own clearer error BaseDexFileReader r = MultiDexFileReader.open(dexBytes);
Defensive patterns
Strategy: validation
Validate before calling
// ensure zip contains at least one .dex before calling open
try (ZipFile zf = new ZipFile(data)) {
boolean hasDex = zf.getEntries().hasMoreElements() &&
java.util.Collections.list(zf.getEntries()).stream().anyMatch(e -> e.getName().endsWith(".dex"));
if (!hasDex) throw new IllegalArgumentException("zip has no classes*.dex entries");
} Try / catch
try {
BaseDexFileReader r = MultiDexFileReader.open(bytes);
} catch (IOException e) {
LOG.error("no dex inside zip: " + e.getMessage());
// fall back to dumping runtime dex for packed APKs
} Prevention
- Confirm APK contents with unzip -l before analysis
- Use MultiDexFileReader.open (all *.dex) rather than expecting exactly classes.dex
- Unpack protected APKs at runtime to recover hidden dex files
When it happens
Trigger: Calling MultiDexFileReader.open(bytes) on a zip/archive that contains no entries ending in .dex (case-sensitive filter), such as a plain zip of resources, an empty APK shell, or an APK where dex entries were stripped or renamed.
Common situations: Passing a renamed .zip or a resource bundle where an APK was expected; APKs processed by tools that removed or renamed classes.dex; encrypted/packed APKs where dex files are hidden until runtime unpacking.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Can not find classes.dex in zip file
- 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
- bad payload for
AI-assisted analysis of pxb1988/dex2jar@b5bda4fb49 (2026-09-08).
Data as JSON: /api/errors/9553245605c428c2.
Report an issue: GitHub.
Appendix: source
Thrown at dex-reader/src/main/java/com/googlecode/d2j/reader/MultiDexFileReader.java:51
if (data.length < 3) {
throw new IOException("File too small to be a dex/zip");
}
if ("dex".equals(new String(data, 0, 3, StandardCharsets.ISO_8859_1))) {// dex
return new DexFileReader(data);
} else if ("PK".equals(new String(data, 0, 2, StandardCharsets.ISO_8859_1))) {// ZIP
TreeMap<String, DexFileReader> dexFileReaders = new TreeMap<>();
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));
}View on GitHub (pinned to b5bda4fb49)