{"record":{"id":"9014e2e006e25aae","repo":"iBotPeaches/Apktool","slug":"could-not-open-apk-file-apkfile-9014e2","errorCode":null,"errorMessage":"Could not open apk file: {apkFile}","messagePattern":"Could not open apk file: (.+?)","errorType":"exception","errorClass":"AndrolibException","httpStatus":null,"severity":"error","filePath":"brut.apktool/apktool-lib/src/main/java/brut/androlib/smali/SmaliDecoder.java","lineNumber":48,"sourceCode":"import java.util.Map;\nimport java.util.Set;\nimport java.util.TreeMap;\nimport java.util.concurrent.ConcurrentHashMap;\nimport java.util.concurrent.atomic.AtomicInteger;\n\npublic class SmaliDecoder {\n    private final ZipDexContainer mDexContainer;\n    private final boolean mDebugMode;\n    private final Set<String> mDexFiles;\n    private final AtomicInteger mInferredApiLevel;\n\n    public SmaliDecoder(File apkFile, boolean debugMode) throws AndrolibException {\n        mDexContainer = new ZipDexContainer(apkFile, null);\n        // ZipDexContainer is lazily initialized and not thread-safe. Eagerly initialize on the constructing thread.\n        try {\n            mDexContainer.getEntry(\"\");\n        } catch (IOException ex) {\n            throw new AndrolibException(\"Could not open apk file: \" + apkFile, ex);\n        }\n        mDebugMode = debugMode;\n        mDexFiles = ConcurrentHashMap.newKeySet();\n        mInferredApiLevel = new AtomicInteger();\n    }\n\n    public Set<String> getDexFiles() {\n        return mDexFiles;\n    }\n\n    public int getInferredApiLevel() {\n        return mInferredApiLevel.get();\n    }\n\n    public void decode(String dexName, File outDir) throws AndrolibException {\n        try {\n            // Fetch the requested dex file from the dex container.\n            ZipDexContainer.DexEntry<DexBackedDexFile> dexEntry = mDexContainer.getEntry(dexName);","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/iBotPeaches/Apktool/blob/79b63384d7d7e22917e6ea8b453272da7012515b/brut.apktool/apktool-lib/src/main/java/brut/androlib/smali/SmaliDecoder.java#L30-L66","documentation":"SmaliDecoder's constructor eagerly initializes the lazily-initialized, non-thread-safe ZipDexContainer by calling getEntry(\"\") on the constructing thread. If that probe throws an IOException, the APK cannot be opened as a dex-bearing ZIP and this AndrolibException is thrown with the file name.","triggerScenarios":"Constructing SmaliDecoder with a file that is not a ZIP, is corrupt, lacks dex entries, or cannot be read. The eager init exists to force all ZIP parsing onto one thread, so any structural ZIP problem surfaces here rather than later during parallel decode.","commonSituations":"Decoding a file that is actually an XAPK/APKM bundle, a partially downloaded APK, an encrypted APK, or a path with wrong permissions — typically in programs driving apktool-lib programmatically.","solutions":["Validate the container first: `unzip -l app.apk` must list classes.dex entries","If the file is a bundle format, extract the real APK first and pass that","Check read permissions and re-obtain the file if the download was truncated (compare size/CRC)","Catch AndrolibException at construction and surface the file name to the user instead of decoding"],"exampleFix":"// before\nSmaliDecoder decoder = new SmaliDecoder(new File(\"app.xapk\"), false);\n\n// after\nFile apk = new File(\"base.apk\");\ntry (ZipFile z = new ZipFile(apk)) {\n    if (z.stream().noneMatch(e -> e.getName().endsWith(\".dex\"))) {\n        throw new IllegalArgumentException(\"No dex entries in \" + apk);\n    }\n}\nSmaliDecoder decoder = new SmaliDecoder(apk, false);","handlingStrategy":"validation","validationCode":"File apk = new File(path);\ntry (ZipFile zf = new ZipFile(apk)) {\n    boolean hasDex = zf.stream().anyMatch(e -> e.getName().endsWith(\".dex\"));\n    if (!hasDex) throw new IllegalArgumentException(\"No dex entries in \" + apk);\n} catch (IOException e) {\n    throw new IllegalArgumentException(\"Not a readable ZIP/APK: \" + apk, e);\n}","typeGuard":null,"tryCatchPattern":"try {\n    SmaliDecoder decoder = new SmaliDecoder(apkFile, debugMode);\n} catch (AndrolibException e) {\n    // constructor failure == file-level problem; do not retry with the same file\n    throw new IllegalArgumentException(\"Cannot open APK for smali decode: \" + apkFile, e);\n}","preventionTips":["Pre-validate that the file is a zip containing dex entries","Extract base APK from bundles before decoding","Construct SmaliDecoder once per file and reuse it for all dex names"],"tags":["apktool","smali","zip","dex"],"backgroundTag":null,"analyzedSha":"79b63384d7d7e22917e6ea8b453272da7012515b","analyzedAt":"2026-08-14T10:43:28.812Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}