Every member’s data is preceded by a local file header, so the archive can be read from the start without its central directory. Most of its fields are repeated in the member’s central directory header, which is the copy readers normally trust. Any encryption header comes straight after the local header and before the data.
Fields
Offsets and sizes are in bytes. The first 30 bytes are fixed. The name and extra field follow them, with their lengths given at offsets 26 and 28. All numbers are unsigned and little-endian.
| Offset | Size | Name | Description |
|---|---|---|---|
0 | 4 | Signature | 50 4B 03 04, the value 0x04034B50. |
4 | 2 | Version needed | The lowest ZIP version that can extract this member, times ten. See the version table. |
6 | 2 | Flags | The general purpose bit flag. Bit 0 says the member is encrypted, bit 3 that a data descriptor follows the data, bit 11 that the name is UTF-8. |
8 | 2 | Method | The compression method. 0 is stored, 8 is Deflate. |
10 | 2 | Time | Modification time in MS-DOS format. |
12 | 2 | Date | Modification date in MS-DOS format. |
14 | 4 | CRC-32 | The CRC-32 of the uncompressed data. |
18 | 4 | Compressed size | The size of the data as stored, including any encryption header. 0xFFFFFFFF if the real value is in a ZIP64 extra field. |
22 | 4 | Uncompressed size | The size after decompression. 0xFFFFFFFF if the real value is in a ZIP64 extra field. |
26 | 2 | Name length | The length of the name, in bytes. |
28 | 2 | Extra field length | The length of the extra field, in bytes. It can differ from the length in the central directory header. |
30 | name length | Name | The file name, with no NUL at the end. |
| 30 + name length | extra length | Extra field | Extra field blocks. |
The data starts at 30 + name length + extra length from the start of the
header. A local header has no comment field and no external attributes. Those are only
in the central directory.
When the values are zero or missing
| Condition | What the local header holds |
|---|---|
| Flag bit 3 set | CRC-32, compressed size and uncompressed size are zero, and the real values are in the data descriptor after the data and in the central directory. Some writers put the real values here anyway. |
| ZIP64 member | Both sizes are 0xFFFFFFFF and a 0x0001 extra block holds both 64-bit sizes. |
| Flag bit 13 set (encrypted central directory) | Method, time, date, CRC-32 and both sizes are masked with zeros and the name is replaced by a sequential hexadecimal value. Fields holding 0xFFFF or 0xFFFFFFFF for ZIP64 are not masked. APPNOTE adds that, as of version 6.2, method and compressed size are not yet masked. |
| Input from standard input | APPNOTE says such a member has no name field, and its time is when compression started. |
Local header and central directory
A reader that has the central directory should use it for sizes, the CRC-32 and the name, and should use the local header only to find where the data starts. The two can legitimately differ in the extra field and in the version needed; Java, for example, has written 10 in one and 20 in the other.
Differences in the method, the CRC-32, the sizes or the name are a sign of damage or of an archive built to confuse one kind of reader. The explorer lists them as problems, leaving out the version, the level bits of the flags and any field that bit 3 or masking allows to differ.
Example
The local header from the sample
archive, for a stored 12-byte file hello.txt.
00000000 50 4B 03 04 0A 00 00 00 00 00 00 60 69 5D 0C 5D PK.........`i].]
00000010 86 8F 0C 00 00 00 0C 00 00 00 09 00 00 00 68 65 ..............he
00000020 6C 6C 6F 2E 74 78 74 llo.txt
| Bytes | Field | Value |
|---|---|---|
0A 00 | Version needed | 10, ZIP 1.0 |
00 00 | Flags | None |
00 00 | Method | 0, stored |
00 60 | Time | 0x6000: 12:00:00 |
69 5D | Date | 0x5D69: 9 November 2026 |
0C 5D 86 8F | CRC-32 | 0x8F865D0C |
0C 00 00 00 | Compressed size | 12 |
0C 00 00 00 | Uncompressed size | 12 |
09 00 | Name length | 9 |
00 00 | Extra field length | 0 |