MuntashirAkon/AppManager · error · DexFileFactory.UnsupportedFileTypeException
InputStream is not a dex, odex file.
Error message
InputStream is not a dex, odex file.
What it means
DexUtils.loadDexContainer() sniffs the input stream by attempting DexBackedDexFile and then DexBackedOdexFile parsing; when both reject the data it throws DexFileFactory.UnsupportedFileTypeException with this message. It means the stream is neither a standard DEX nor an ODEX file, so no dex container can be produced from it.
Source
Thrown at app/src/main/java/io/github/muntashirakon/AppManager/dex/DexUtils.java:229
javaClass.decompile();
return javaClass.getCode();
}
}
@NonNull
public static DexBackedDexFile loadDexContainer(@NonNull InputStream inputStream, int api) throws IOException {
Opcodes opcodes = api < 0 ? Opcodes.getDefault() : Opcodes.forApi(api);
try {
return DexBackedDexFile.fromInputStream(opcodes, inputStream);
} catch (DexBackedDexFile.NotADexFile ex) {
// just eat it
}
try {
return DexBackedOdexFile.fromInputStream(opcodes, inputStream);
} catch (DexBackedOdexFile.NotAnOdexFile ex) {
// just eat it
}
throw new DexFileFactory.UnsupportedFileTypeException("InputStream is not a dex, odex file.");
}
}
View on GitHub (pinned to 0152f468fc)
Solutions
- Verify the stream starts with the DEX magic bytes 0x64 0x65 0x78 0x0A ("dex\n") or ODEX magic "dey\n" before calling loadDexContainer
- If the input is an APK/JAR/ZIP, extract the classes*.dex entries first and feed those streams
- If the input is VDEX/CDex (newer ART formats), convert it back to dex with external tools — this library does not parse them
- Re-obtain the file and check its integrity (size/hash) in case of truncation or corruption
Example fix
// before
DexContainer container = DexUtils.loadDexContainer(stream, opcodes);
// after
byte[] header = new byte[4];
try (DataInputStream in = new DataInputStream(stream)) {
in.readFully(header);
if (!(new String(header, "ISO_8859_1").startsWith("dex\n"))) {
throw new IllegalArgumentException("Not a DEX file (bad magic)");
}
}
DexContainer container = DexUtils.loadDexContainer(new ByteArrayInputStream(header), opcodes); Defensive patterns
Strategy: try-catch
Validate before calling
byte[] magic = new byte[4]; int n = stream.read(magic); if (n < 4 || !(new String(magic, 0, 4, StandardCharsets.ISO_8859_1).startsWith("dex\n") || new String(magic, 0, 4, StandardCharsets.ISO_8859_1).startsWith("dey\n"))) throw new IllegalArgumentException("Not a dex/odex stream"); Type guard
boolean looksLikeDex(byte[] b) { return b != null && b.length > 7 && b[0]=='d' && b[1]=='e' && b[2]=='x' && b[3]=='\n'; } Try / catch
try { DexContainer c = DexUtils.loadDexContainer(stream, opcodes); } catch (DexFileFactory.UnsupportedFileTypeException e) { /* fall back to zip extraction of classes*.dex or inform user the file is unsupported */ } Prevention
- Always extract classes*.dex from APK/ZIP archives before parsing
- Check file magic bytes before feeding streams to dex parsers
- Reject VDEX/CDEX artifacts explicitly with a clear message
- Verify download integrity (size/hash) to avoid truncated dex files
When it happens
Trigger: Passing an InputStream to DexUtils.loadDexContainer() whose bytes are not DEX (magic "dex\n") or ODEX (magic "dey\n") — e.g. a ZIP/APK, a VDEX/CDex artifact, a text file, or a truncated/corrupted dex.
Common situations: Extracting the wrong entry from an APK (resources.arsc instead of classes.dex); passing a .vdex file from newer Android art; passing the APK itself instead of the inner dex; downloading a dex that was truncated or HTML-error-paged.
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
- ODEX isn't supported.
- {className} could not be found.
- {parserErrors} syntax errors during parsing and/or lexing.
- {syntaxErrors} syntax errors during dex creation
- Could not generate class from smali.
AI-assisted analysis of MuntashirAkon/AppManager@0152f468fc (2026-09-12).
Data as JSON: /api/errors/284821497bfa3a71.
Report an issue: GitHub.