{
  "schemaVersion": "1.0",
  "canonicalPage": "https://fileformat.co/ext/aab",
  "inspectorUrl": "https://fileformat.co/inspect",
  "spec": {
    "slug": "aab",
    "extension": ".aab",
    "aliases": [],
    "name": "Android App Bundle",
    "shortName": "Android AAB",
    "category": "devtools-security",
    "tier": 1,
    "summary": "Google Play publishing format packaging `BundleConfig.pb`, Protocol-Buffer encoded `base/manifest/AndroidManifest.xml`, and DEX bytecode inside a modular ZIP container.",
    "technicalNotes": "Unlike installable `.apk` files (which place binary-XML `AndroidManifest.xml` at root), `.aab` stores Protobuf-serialized manifests under `<module>/manifest/AndroidManifest.xml` plus root `BundleConfig.pb`. MIME note: `application/x-authorware-bin` seen in legacy MIME databases refers to Adobe Authorware (a historical extension collision), NOT Android App Bundle—serve `.aab` as `application/vnd.android.aab` or fall back to `application/octet-stream`.",
    "mimeTypes": [
      "application/vnd.android.aab",
      "application/octet-stream",
      "application/zip"
    ],
    "identifiers": {
      "specUrl": "https://developer.android.com/guide/app-bundle/app-bundle-format"
    },
    "binarySignature": {
      "endianness": "little",
      "magicBytes": [
        {
          "offset": 0,
          "hex": "50 4B 03 04",
          "ascii": "PK..",
          "description": "PKZIP bundle containing BundleConfig.pb & base/manifest/AndroidManifest.xml"
        }
      ],
      "containerFamily": "zip",
      "headerLayout": [
        {
          "offset": "0x00 - 0x03",
          "byteOffset": 0,
          "byteLength": 4,
          "lengthLabel": "4 B",
          "dataType": "uint32_le",
          "fieldName": "zip_magic",
          "description": "PKZIP Local File Header"
        },
        {
          "offset": "0x1E+",
          "byteOffset": 30,
          "byteLength": 15,
          "lengthLabel": "var",
          "dataType": "utf8",
          "fieldName": "bundle_config",
          "description": "'BundleConfig.pb' protobuf descriptor"
        }
      ]
    },
    "securityProfile": {
      "riskLevel": "medium",
      "allowsArbitraryCodeOrMacros": true,
      "xxeRisk": false,
      "polyglotPrependRisk": true,
      "pickleDeserializationRisk": false,
      "uploadValidationNotes": "Distinguish .aab from .apk by requiring root BundleConfig.pb and verifying JAR/APK signature blocks (META-INF/) in release pipelines."
    },
    "codeSnippets": {
      "python": "import sys, zipfile\nwith zipfile.ZipFile(sys.argv[1], \"r\") as zf:\n    names = set(zf.namelist())\n    assert \"BundleConfig.pb\" in names, \"Missing BundleConfig.pb\"\n    print(f\"Valid Android AAB ({len(names)} entries)\")",
      "typescript": "export async function checkAabZip(file: File) {\n  const dv = new DataView(await file.slice(0, 4).arrayBuffer());\n  return dv.getUint32(0, true) === 0x04034b50;\n}",
      "rust": "use std::{fs::File, io::Read};\nfn main() -> std::io::Result<()> {\n    let mut b = [0u8; 4];\n    File::open(std::env::args().nth(1).expect(\"usage: <prog> <file>\"))?.read_exact(&mut b)?;\n    println!(\"AAB ZIP sig: {:02X?}\", b);\n    Ok(())\n}",
      "go": "package main\nimport (\"archive/zip\"; \"fmt\"; \"os\")\nfunc main() {\n    r, err := zip.OpenReader(os.Args[1])\n    if err != nil {\n        fmt.Fprintln(os.Stderr, \"open zip:\", err)\n        os.Exit(1)\n    }\n    defer r.Close()\n    fmt.Println(\"AAB entries:\", len(r.File))\n}"
    },
    "relatedFormats": [
      "ipa",
      "wasm",
      "onnx"
    ],
    "verifiedAt": "2026-11-14T16:09:03Z"
  },
  "samples": [
    {
      "id": "aab-minimal",
      "filename": "minimal-base.aab",
      "variant": "minimal",
      "title": "Android App Bundle Unsigned Container Fixture (.aab)",
      "description": "UNSIGNED container-structure fixture: real ZIP with BundleConfig.pb, base/manifest/AndroidManifest.xml and dex\\n039 header stub. NOT a Play-signed publishable bundle.",
      "localPath": "/fixtures/v1/aab/minimal-base.aab",
      "cdnUrl": "https://fileformat.co/fixtures/v1/aab/minimal-base.aab",
      "sizeBytes": 450,
      "sha256": "2564e236b066e8187c9c16be9d3e13332ce02e5d69a7171cf91372d96ebf16f8",
      "expectValid": true
    },
    {
      "id": "aab-realistic",
      "filename": "release-module.aab",
      "variant": "realistic",
      "title": "Multi-Resource AAB Unsigned Container Fixture",
      "description": "UNSIGNED fixture adding base/resources.pb alongside BundleConfig.pb and classes.dex to distinguish .aab from legacy .apk.",
      "localPath": "/fixtures/v1/aab/release-module.aab",
      "cdnUrl": "https://fileformat.co/fixtures/v1/aab/release-module.aab",
      "sizeBytes": 572,
      "sha256": "875c6a215d912e50d0274d36512ef9c5b9564b5c10f1822e631636234fe3016d",
      "expectValid": true
    },
    {
      "id": "aab-edge-case",
      "filename": "truncated-bundle.aab",
      "variant": "edge-case",
      "title": "Truncated Android App Bundle",
      "description": "AAB archive truncated inside the ZIP Central Directory — zipfile must raise.",
      "localPath": "/fixtures/v1/aab/truncated-bundle.aab",
      "cdnUrl": "https://fileformat.co/fixtures/v1/aab/truncated-bundle.aab",
      "sizeBytes": 436,
      "sha256": "af8a9755a801d6c9890cbf897fe1cc1314cfc39a5769e1d56d8418fc8a63883c",
      "expectValid": false,
      "edgeCaseTag": "Truncated Central Directory"
    }
  ]
}