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

  1. Confirm the input is a real APK containing classes.dex (unzip -l).
  2. If entries use different names/casing, rename them to classes.dex / classes2.dex or unpack and rebuild the APK.
  3. If the APK is protected/packed, dump the runtime dex files first (e.g. with a unpacker) and pass those dex bytes instead.
  4. 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

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


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)