ByteScope

Android APK file format

An Android application package — a ZIP archive of compiled code, resources and a manifest.

MIME type
application/vnd.android.package-archive
Extensions
.apk
Category
Archives & compression

Magic-number signature

0x00000000504B0304PK··'PK' — it is a ZIP

Inside the ZIP: an 'AndroidManifest.xml' entry (and usually 'classes.dex').

About the Android APK format

An APK is a ZIP archive with a required inner layout and one unusual extra: a signing block wedged between the last file's data and the ZIP central directory, in space the format leaves unclaimed. That is what makes an APK verifiable as a whole file rather than entry by entry, and it is also why appending anything to an APK, or rebuilding it with an ordinary ZIP tool, silently destroys the v2 and later signatures. Inside, AndroidManifest.xml is stored as Android binary XML rather than text, resources are indexed by resources.arsc, and the code lives in one or more classes.dex files.

Header layout, byte by byte

OffsetLengthFieldMeaning
04Local file header signature50 4B 03 04 — an APK is a ZIP, byte for byte, and nothing at the front of the file says Android. Each stored entry begins with one of these headers; only the one at offset 0 is at a fixed position.
42Version needed to extractMinimum reader version times ten: 10 for stored entries, 20 for deflate — the two values that cover essentially every entry in an APK, since Android's runtime does not accept the exotic compression methods a general ZIP allows.
62General purpose bit flagBit 11 declares the entry name UTF-8 and is set by modern build tools. Bit 3, which moves the sizes and CRC after the data, must not be set in an APK because the runtime maps entries directly and needs their sizes up front.
82Compression method0 stored or 8 deflate. resources.arsc must be stored uncompressed and aligned so the runtime can memory-map it, and native libraries in lib/ are usually stored too, so a hex dump of an APK shows long runs of readable data where a plain ZIP would show compressed noise.
144CRC-32CRC-32 of the entry's uncompressed bytes, at offset 14 with the compressed and uncompressed sizes following at 18 and 22. These are the values the installer checks when unpacking, separate from and unrelated to the APK's signature.
262File name lengthLength in bytes of the entry name that starts at offset 30. Together with the extra-field length at 28 it fixes where this entry's data begins — and the extra field in an APK is often padding inserted by zipalign to push the next entry onto a 4-byte or 16 KiB boundary.
30variableFirst entry nameThe only place in the header that hints this is Android at all. Which name comes first depends on the build tool, so treat it as a hint rather than a test: what identifies an APK is the presence of AndroidManifest.xml and normally classes.dex somewhere in the central directory.
variable16APK Signing Block magicThe 16 ASCII bytes 'APK Sig Block 42', sitting immediately before the ZIP central directory, preceded by an 8-byte size that repeats the block's own length. Reading the block backwards from the central directory offset is how a verifier finds the v2, v3 and v3.1 signature records.
-224End of central directory signature50 4B 05 06, 22 bytes from the end when there is no archive comment. Every reader starts here, walks back to the central directory, and only then knows what is in the file — which is why an APK with an intact first entry can still fail to install.
-64Offset of the central directoryWhere the central directory begins, counted from the start of the file. It is also the anchor for the signing block, so any tool that rewrites the archive and moves this value without re-signing produces an APK the installer rejects.

Telling it apart from its neighbours

Easily confused withHow to tell
ZIPThere is no byte-level difference at the front — an APK is a ZIP. What identifies it is content: AndroidManifest.xml at the archive root, normally classes.dex, usually resources.arsc, and META-INF holding the v1 signature files. If those entries are absent it is a plain ZIP, whatever the extension says.
Java JARBoth are ZIPs with a META-INF directory, and an APK is historically a JAR. The separator is what else is there: a JAR holds .class entries and META-INF/MANIFEST.MF, an APK holds .dex entries and AndroidManifest.xml, and only an APK carries the 'APK Sig Block 42' magic before the central directory.
aab/apks/xapk/apkmAll ZIPs, none of them installable APKs. An .apks bundle from bundletool contains toc.pb plus split APKs; an .xapk contains manifest.json plus APKs and OBB data; an .apkm carries info.json. Each of those markers sits at the archive root, so the first entry names in the central directory are what tells them apart — and the APKs inside are the real packages.
AndroidManifest.xml (binary XML)Worth knowing because people extract it and find gibberish. The manifest inside an APK is not text: it is a chunk-structured binary XML file whose first 16-bit value is the chunk type 0x0003, followed by a 16-bit header size, so a hex dump starts 03 00 08 00. Decoding it needs the string pool and the resource map, not an XML parser.

How these files break

  • Rebuilt with an ordinary ZIP tool. Unpacking an APK and re-zipping it produces a structurally perfect archive whose signing block has been dropped and whose resources.arsc is now compressed and misaligned. The file opens fine in any archive viewer and is refused by the installer, which is the single most common self-inflicted APK failure.
  • Anything appended to the file. Some distribution wrappers stuff data after the central directory to carry a channel or referrer id. ZIP tolerates it, but the v2 signature covers the file up to the central directory offset, so the signature check now sees a different file than the one that was signed.
  • Truncation. As with any ZIP the end of central directory record goes first, so a partially downloaded APK has every local header intact and no way to list its contents. Recovery means scanning forward for 50 4B 03 04, and an APK reassembled that way will not verify even if every entry is recovered.
  • Entries renamed or reordered by a repackaging tool. The signature covers entry names, so renaming even one file, or letting a tool normalise the order and drop the zipalign padding in the extra fields, invalidates v2 and later signatures while leaving a perfectly valid ZIP behind.

Where the format stands today

The APK is the only thing Android installs. App bundles changed how apps are published — a developer uploads an .aab and Google Play generates per-device split APKs from it — but the artefact that lands on a phone is still an APK, and sideloading, enterprise distribution, F-Droid and every alternative store deal in APKs directly. That is why the surrounding zoo of container formats exists: .aab for publishing, .apks, .xapk and .apkm for shipping a set of splits as one download, all of them ZIPs wrapping the real packages. For inspection the format is unusually rewarding: permissions, components, minimum SDK, signing certificates, native architectures and the full class list are all readable from the archive without running anything, which is what an APK analyser does.

Open Android APK files on this site

Every one of these runs in your browser — the file never leaves your machine.

Related formats

Formats that are easy to confuse with Android APK — compare their leading bytes.

FormatFirst bytesExtension
ZIP50 4B 03 04.zip
Java JAR50 4B 03 04.jar
Android DEX64 65 78 0A.dex

Frequently asked questions

What is a magic number in a file?

The first few bytes of a file, which identify its format regardless of what the name says. A PNG always starts with 89 50 4E 47; a ZIP with 50 4B 03 04. Operating systems, browsers and the file command all read these bytes rather than trusting the extension, which is why renaming a file does not change what it actually is.

How do I check a file's magic number myself?

On macOS or Linux, xxd -l 16 yourfile prints the first 16 bytes; on Windows, Format-Hex -Path yourfile -Count 16 in PowerShell. Or drop the file into the File Type Identifier on this site, which reads the bytes locally and names the format for you — nothing is uploaded.

Why do two formats share the same magic number?

Because one is built on the other. Every docx, xlsx, pptx, apk, jar and epub begins with the ZIP signature, since all of them are ZIP archives underneath; telling them apart means looking at the entries inside. Java class files and macOS universal binaries both start with CA FE BA BE and are distinguished by the field that follows.

Can a file have no magic number at all?

Yes. Text-based formats — XML, HTML, JSON, SVG, CSV — have no fixed byte signature, so they are recognized structurally instead: a leading <?xml declaration, a <svg element, or a { followed by a quoted key. That detection is a good guess rather than a certainty, which is why this reference marks those formats as probe-detected.

Does a matching magic number mean the file is safe?

No. It tells you what the format is, not whether the contents are harmless — a genuine PDF or docx can still carry a malicious payload. Identifying the true type is a useful first check, especially when the extension disagrees with the bytes, but it is not a malware scan.

Have a file that might be in the Android APK format? Identify it with the File Type Identifier — it reads the magic number locally, nothing is uploaded. Or browse all formats.