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
- Check the file starts with the ZIP magic bytes 'PK' (0x50 0x4B) before parsing
- Re-download or re-obtain the APK file
- Verify the file size matches the expected size / checksum
- 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
- Verify checksums/sizes of downloaded APK files
- Never treat HTML error pages or split blobs as APK files
- Check 'PK' magic bytes before parsing
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.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Failed to read AndroidManifest.xml
- Missing {MANIFEST_FILE}
- Could not cache the APK file
- No manifest found.
- "manifest" has duplicate "application" tags.
AI-assisted analysis of MuntashirAkon/AppManager@0152f468fc (2026-09-12).
Data as JSON: /api/errors/be6b9e08ca8f20c0.
Report an issue: GitHub.