The extra field is where a ZIP header carries anything the fixed fields do not: 64-bit sizes, exact times, Unix owners, Unicode names, alignment padding. Each local and central header has its own, and the two can differ.
Block layout
An extra field is a sequence of blocks, with no padding between them.
| Offset | Size | Name | Description |
|---|---|---|---|
0 | 2 | Header ID | Says what the block is. |
2 | 2 | Data size | The size of the data after these 4 bytes. |
4 | data size | Data | The block’s data. |
IDs 0 to 31 are reserved for PKWARE. The whole extra field is limited by its 16-bit length, and APPNOTE says the name, extra field and comment together should not generally exceed 65,535 bytes. A reader should skip IDs it does not know, using the data size, and check that each block fits.
Some writers put bytes in the extra field that are not blocks. Older Android
zipalign padded with zeros, too few to be a block, and at least one
program kept unrelated data there. The explorer treats fewer than 4 leftover bytes as
padding, and a field whose first block cannot fit as unstructured data.
Header IDs
PKWARE’s IDs
| ID | Name |
|---|---|
0x0001 | ZIP64 extended information |
0x0007 | AV Info |
0x0008 | Extended language encoding (reserved) |
0x0009 | OS/2 |
0x000A | NTFS |
0x000C | OpenVMS |
0x000D | Unix |
0x000E | File stream and fork descriptors (reserved) |
0x000F | Patch descriptor |
0x0014 | PKCS#7 store for X.509 certificates |
0x0015 | X.509 certificate ID and signature for a file |
0x0016 | X.509 certificate ID for the central directory |
0x0017 | Strong encryption header |
0x0018 | Record management controls |
0x0019 | PKCS#7 encryption recipient certificate list |
0x0020 | Timestamp record (reserved) |
0x0021 | Policy decryption key record |
0x0022 | Smartcrypt key provider record |
0x0023 | Smartcrypt policy key data record |
0x0065 | IBM S/390 (Z390), AS/400 (I400) attributes, uncompressed |
0x0066 | IBM S/390 (Z390), AS/400 (I400) attributes, compressed (reserved) |
0x4690 | POSZIP 4690 (reserved) |
Third-party IDs
APPNOTE lists these IDs, assigned or taken by other software.
| ID | Name |
|---|---|
0x07C8 | Macintosh |
0x1986 | Pixar USD |
0x2605 | ZipIt Macintosh |
0x2705 | ZipIt Macintosh 1.3.5 and later |
0x2805 | ZipIt Macintosh 1.3.5 and later |
0x334D | Info-ZIP Macintosh |
0x4154 | Tandem |
0x4341 | Acorn SparkFS |
0x4453 | Windows NT security descriptor (binary ACL) |
0x4704 | VM/CMS |
0x470F | MVS |
0x4854 | THEOS (old) |
0x4B46 | FWKCS MD5 |
0x4C41 | OS/2 access control list (text ACL) |
0x4D49 | Info-ZIP OpenVMS |
0x4D63 | Macintosh SmartZIP |
0x4F4C | Xceed original location |
0x5356 | AOS/VS (ACL) |
0x5455 | Extended timestamp |
0x554E | Xceed Unicode |
0x5855 | Info-ZIP Unix (original) |
0x6375 | Info-ZIP Unicode comment |
0x6542 | BeOS and BeBox |
0x6854 | THEOS |
0x7075 | Info-ZIP Unicode path |
0x7441 | AtheOS and Syllable |
0x756E | ASi Unix |
0x7855 | Info-ZIP Unix (new) |
0x7875 | Info-ZIP Unix (newer owner IDs) |
0x9901 | AE-x encryption structure |
0x9902 | Unknown |
0xA11E | Data stream alignment (Apache Commons Compress) |
0xA220 | Microsoft Open Packaging growth hint |
0xCAFE | Java JAR marker |
0xD935 | Android ZIP alignment |
0xE57A | Korean ZIP code page |
0xFD4A | SMS/QDOS |
ZIP64, 0x0001
Described on the ZIP64 page. The fields present depend on which header fields hold sentinels.
NTFS, 0x000A
Three 8-byte file times in NTFS format, in units of 100 nanoseconds since 1 January 1601 UTC.
| Size | Name | Description |
|---|---|---|
| 2 | Tag | 0x000A |
| 2 | TSize | The total size of what follows. |
| 4 | Reserved | Zero. |
| 2 | Tag1 | 0x0001, the only attribute defined. |
| 2 | Size1 | 24. |
| 8 | Mtime | Last modification. |
| 8 | Atime | Last access. |
| 8 | Ctime | Creation. |
Patch descriptor, 0x000F
Marks a member as patch data. After the tag and size:
| Size | Name |
|---|---|
| 2 | Version |
| 4 | Flags |
| 4 | Old size |
| 4 | Old CRC |
| 4 | New size |
| 4 | New CRC |
Flags bit 0 is for auto-detection, bit 1 means a self-patch, bits 4 and 5 are the action (0 none, 1 add, 2 delete, 3 patch), bits 8 and 9, 10 and 11, and 12 and 13 are the reaction to an absent, newer and unknown file (0 ask, 1 skip, 2 ignore, 3 fail). The rest are reserved.
PKWARE Unix, 0x000D
In the local header only.
| Size | Name | Description |
|---|---|---|
| 2 | Tag | 0x000D |
| 2 | TSize | The total size of what follows, at least 12. |
| 4 | Atime | Last access, Unix seconds. |
| 4 | Mtime | Last modification, Unix seconds, UTC. |
| 2 | Uid | User ID. |
| 2 | Gid | Group ID. |
| varies | Data | For a symbolic or hard link, its target with no NUL; for a device, two 4-byte little-endian numbers, major then minor. |
Extended timestamp, 0x5455
Info-ZIP’s Unix times, also known as UT.
| Size | Name | Description |
|---|---|---|
| 2 | Tag | 0x5455 |
| 2 | TSize | 1 + 4 × the number of times present. |
| 1 | Flags | Bit 0 modification time present, bit 1 access time, bit 2 creation time. Bits 3 to 7 are reserved and must be clear. |
| 4 | ModTime | Present if flagged. |
| 4 | AcTime | Present if flagged. |
| 4 | CrTime | Present if flagged. |
Times are signed 32-bit Unix seconds, UTC. In a central header, the flags still describe the local header but only the modification time is stored, so TSize is 5 or 1. A reader that decodes by flags alone reads off the end of a central block. Use TSize.
Info-ZIP Unix type 1, 0x5855
Obsolete, and to be read but not written. UX in the file. Ignored if
0x5455 or 0x7855 is also present.
| Size | Name | Description |
|---|---|---|
| 4 | AcTime | Access time, Unix seconds. |
| 4 | ModTime | Modification time, Unix seconds. |
| 2 | UID | Local header only, and optional: TSize says. |
| 2 | GID | Local header only, and optional: TSize says. |
Info-ZIP Unix type 2, 0x7855
Ux in the file. In a local header, TSize is 4, followed by UID (2) and
GID (2). In a central header, TSize is 0 and there is no data: its presence only says
the local header has the field.
Info-ZIP Unix type 3, 0x7875
ux in the file. It can hold larger owner IDs than 0x7855, whose values
it overrides.
| Size | Name | Description |
|---|---|---|
| 2 | Tag | 0x7875 |
| 2 | TSize | |
| 1 | Version | 1. Ignore the block if unknown. |
| 1 | UIDSize | Size of the next field. |
| UIDSize | UID | Little-endian. |
| 1 | GIDSize | Size of the next field. |
| GIDSize | GID | Little-endian. |
Unicode path, 0x7075
up in the file. Used to give a UTF-8 name while the header keeps an older
encoding for old tools. See File names.
| Size | Name | Description |
|---|---|---|
| 2 | Tag | 0x7075 |
| 2 | TSize | |
| 1 | Version | 1. Ignore the block if unknown. |
| 4 | NameCRC32 | The CRC-32 of the header’s name field. |
| TSize − 5 | UnicodeName | The name, UTF-8, no byte order mark. |
If the CRC-32 does not match the header’s name, the header was changed by a tool that did not update this block, so a reader must ignore it and use the header’s name. APPNOTE says these blocks should not be created when bit 11 is set.
Unicode comment, 0x6375
uc in the file. The same layout as the Unicode path, in a central header,
with ComCRC32 computed over the central header’s comment.
WinZip AES, 0x9901
Marks a member as AE-1 or AE-2 encrypted. Present in both headers, with method set to 99.
| Size | Name | Description |
|---|---|---|
| 2 | Tag | 0x9901 |
| 2 | TSize | 7, at present. |
| 2 | Version | 0x0001 AE-1 or 0x0002 AE-2. |
| 2 | Vendor ID | The characters AE. |
| 1 | Strength | 0x01 128-bit, 0x02 192-bit, 0x03 256-bit. |
| 2 | Method | The real compression method. |
See WinZip AES for how the data is protected.
FWKCS MD5, 0x4B46
| Size | Name | Description |
|---|---|---|
| 2 | Tag | 0x4B46 |
| 2 | TSize | 0x0013, 19. |
| 3 | Prefix | MD5 |
| 16 | Hash | The MD5 of the uncompressed file, low byte first. |
JAR marker, 0xCAFE
Java’s JarOutputStream adds this block to the first entry it writes, with
a data size of 0 and no data, as the first block in the extra field. It is left out if the
entry already has it. Other entries do not get it.
Alignment and padding
Some formats need a member’s data to start at a multiple of some boundary, so that it can be used straight from the file, or in the case of Open Packaging so that it can grow later. Padding goes in an extra block in the local header.
Apache alignment, 0xA11E
| Size | Name | Description |
|---|---|---|
| 2 | Tag | 0xA11E |
| 2 | TSize | 2 + the padding size. |
| 2 | Alignment | Low 15 bits: the data’s minimum alignment. Bit 15: 0 the method should not change, 1 it may change when recompressing. |
| varies | Padding | Zero bytes. |
Android alignment, 0xD935
| Size | Name | Description |
|---|---|---|
| 2 | Tag | 0xD935 |
| 2 | TSize | 2 + the padding size. |
| 2 | Alignment | The multiple the data is aligned to, such as 4 or 4096. |
| varies | Padding | Zero bytes. |
Open Packaging growth hint, 0xA220
| Size | Name | Description |
|---|---|---|
| 2 | Tag | 0xA220 |
| 2 | TSize | The size of the signature, initial padding value and padding. |
| 2 | Signature | 0xA028. |
| 2 | PadVal | The initial padding value. APPNOTE does not say more about it. |
| varies | Padding | Filled with NUL characters. |