MuntashirAkon/AppManager · error · ApkFile.ApkFileException

Malformed APK: not a ZIP archive

Error message

Malformed APK: not a ZIP archive

What it means

getManifestFromApk parses the APK with apksig's ZIP machinery; when findZipSections cannot locate valid End-of-Central-Directory records, the file is not a ZIP and this ApkFileException is thrown with the message 'Malformed APK: not a ZIP archive'.

Source

Thrown at app/src/main/java/io/github/muntashirakon/AppManager/apk/ApkUtils.java:155

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            return apkName.replaceAll("%min_sdk%", String.valueOf(packageInfo.applicationInfo.minSdkVersion));
        }
        return apkName;
    }

    public static boolean isSplitApk(@NonNull ApplicationInfo info) {
        return info.splitPublicSourceDirs != null && info.splitPublicSourceDirs.length > 0;
    }

    @NonNull
    public static ByteBuffer getManifestFromApk(File apkFile) throws ApkFile.ApkFileException {
        try (RandomAccessFile in = new RandomAccessFile(apkFile, "r")) {
            DataSource apk = DataSources.asDataSource(in);
            com.android.apksig.apk.ApkUtils.ZipSections apkSections;
            try {
                apkSections = com.android.apksig.apk.ApkUtils.findZipSections(apk);
            } catch (ZipFormatException e) {
                throw new ApkFile.ApkFileException("Malformed APK: not a ZIP archive", e);
            }
            List<CentralDirectoryRecord> cdRecords;
            try {
                cdRecords = ZipUtils.parseZipCentralDirectory(apk, apkSections);
            } catch (ApkFormatException e) {
                throw new ApkFile.ApkFileException(e.getMessage(), e);
            }
            try {
                return getAndroidManifestFromApk(
                        cdRecords,
                        apk.slice(0, apkSections.getZipCentralDirectoryOffset()));
            } catch (ApkFormatException e) {
                throw new ApkFile.ApkFileException(e.getMessage(), e);
            } catch (ZipFormatException e) {
                throw new ApkFile.ApkFileException("Failed to read " + MANIFEST_FILE, e);
            }
        } catch (IOException e) {
            throw new ApkFile.ApkFileException(e.getMessage(), e);

View on GitHub (pinned to 0152f468fc)

Solutions

  1. Check the file starts with the ZIP magic bytes 'PK' (0x50 0x4B) before parsing
  2. Re-download or re-obtain the APK file
  3. Verify the file size matches the expected size / checksum
  4. Check logs of whatever produced the file (download manager, cache) for truncation

Example fix

// before
getManifestFromApk(suspiciousFile);
// after
try (RandomAccessFile raf = new RandomAccessFile(suspiciousFile, "r")) {
    byte[] magic = new byte[2];
    raf.readFully(magic);
    if (magic[0] != 'P' || magic[1] != 'K') throw new IllegalArgumentException("Not a ZIP/APK");
}
getManifestFromApk(suspiciousFile);
Defensive patterns

Strategy: validation

Validate before calling

static boolean looksLikeZip(File f) throws IOException {
    try (RandomAccessFile raf = new RandomAccessFile(f, "r")) {
        byte[] magic = new byte[2];
        raf.readFully(magic);
        return magic[0] == 'P' && magic[1] == 'K';
    }
}

Try / catch

try {
    return ApkUtils.getManifestFromApk(apkFile);
} catch (ApkFile.ApkFileException e) {
    if (e.getMessage() != null && e.getMessage().contains("not a ZIP")) {
        // re-download / reject the file
    }
    throw e;
}

Prevention

When it happens

Trigger: Passing a File to getManifestFromApk(File) whose content is not a ZIP archive — findZipSections throws ZipFormatException.

Common situations: Download truncated/interrupted APK, HTML error page saved as .apk, base64 or PEM file mislabeled, corrupt cache, or a split-APK base blob that is actually not a zip.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of MuntashirAkon/AppManager@0152f468fc (2026-09-12). Data as JSON: /api/errors/be6b9e08ca8f20c0. Report an issue: GitHub.