Every member of a GNU tar archive starts with a header of exactly 512 bytes. It holds
the member’s name, permissions, owner, size, time and type, and, in bytes 345 to 511,
GNU tar’s own fields: access and change times, a multi-volume offset and a sparse map.
Numbers are written as octal text, or in base-256 when they are too large. The layout is
oldgnu_header in GNU tar’s tar.h.
Fields
Offsets and sizes are in bytes, in decimal. Bytes 0 to 344 have the same fields as a ustar header; bytes 345 to 511 are GNU tar’s own.
| Offset | Size | Type | Name | Description |
|---|---|---|---|---|
0 | 100 | text | name | The member’s path, up to the first NUL. There is no prefix: a longer path goes in a long-name entry. |
100 | 8 | octal | mode | Permission bits: 4000 setuid, 2000 setgid, 1000 sticky, then read, write and execute for owner (400, 200, 100), group (40, 20, 10) and others (4, 2, 1). Some writers store the whole file mode, such as 0100644 for a regular file. |
108 | 8 | octal | uid | The owner’s numeric user ID. |
116 | 8 | octal | gid | The owner’s numeric group ID. |
124 | 12 | octal or base-256 | size | The number of bytes of data after the header. For a sparse file, the stored bytes only. |
136 | 12 | octal or base-256 | mtime | The modification time, in seconds since 1 January 1970 UTC. |
148 | 8 | octal | chksum | The header’s checksum. |
156 | 1 | character | typeflag | What the member is: see type flags. |
157 | 100 | text | linkname | The target of a hard or symbolic link; a longer one goes in a K entry. |
257 | 6 | characters | magic | ustar and a space (75 73 74 61 72 20). See magic. |
263 | 2 | characters | version | A space and a NUL (20 00). |
265 | 32 | text | uname | The owner’s user name, used in place of uid when that user exists. |
297 | 32 | text | gname | The owner’s group name. |
329 | 8 | octal | devmajor | The major device number, for character and block devices. |
337 | 8 | octal | devminor | The minor device number. |
345 | 12 | octal or base-256 | atime | The access time, in incremental archives. Zeros otherwise. |
357 | 12 | octal or base-256 | ctime | The status change time, in incremental archives. |
369 | 12 | octal | offset | For a multi-volume continuation (M), where this part starts in the whole file. |
381 | 4 | unused | longnames | Not used. |
385 | 1 | unused | unused | Padding. |
386 | 96 | 4 × 24 bytes | sparse | Four sparse map entries, each a 12-byte octal offset and a 12-byte octal length. |
482 | 1 | flag | isextended | Non-zero when sparse extension blocks follow the header. |
483 | 12 | octal or base-256 | realsize | A sparse file’s full size, with the holes put back. |
495 | 17 | padding | pad | Zeros, bringing the header to 512 bytes. |
Names
Text fields are padded with NUL bytes, and a value that fills the field has no NUL. A
GNU header has no prefix: bytes 345 to 499, where ustar keeps one, hold the GNU fields.
A path longer than 100 characters, or a link target longer than 100, is written in a
long-name entry of type
L or K just before the member, and the member’s own
name holds the first 100 characters.
Writers end a folder’s name with /. Names are bytes with no stated
encoding; the explorer shows them as UTF-8 when they are valid UTF-8, and as Latin-1
when not.
Go before version 1.8 wrote a ustar prefix into GNU headers by mistake: its reader notes that “the logic incorrectly believed that the old GNU format had a prefix field”. Go now reads the access and change times of a GNU header as a prefix if they do not parse as numbers. The explorer reports such headers.
Numbers
The GNU manual: “Each numeric field of width w contains w minus 1
digits, and a null.” The digits are octal, with leading zeros. With 7 digits,
mode, uid and gid reach 2,097,151; with 11
digits, size and the times reach 8,589,934,591, which is 8 GiB less one
byte.
Larger values are written in base-256. If the top bit of the field’s first byte is set,
the rest of the field is a big-endian two’s complement binary number; bit 6 of the
first byte is the sign. A first byte of 80 marks a positive number and
FF a negative one. libarchive’s tar(5) says GNU tar uses it for the size
and the three times; star and libarchive use it in any numeric field, and readers
accept it in any header.
Go’s test archive writer-big.tar holds a GNU header for a 16 GiB file. Its
size field, at offset 124 (0x7C), is:
80 00 00 00 00 00 00 04 00 00 00 00
80 marks base-256; the rest is 0x4_0000_0000, 17,179,869,184 bytes.When reading octal, GNU tar skips one leading NUL and any leading spaces, reads octal digits, and requires the next byte to be a space or a NUL. The explorer reads numbers the same way; that description of GNU tar is from memory of its source and is not confirmed.
Checksum
The checksum is the sum of all 512 bytes of the header, each read as an unsigned
number, with the eight bytes of chksum itself counted as spaces.
- Take the 512 bytes. Replace bytes 148 to 155 with eight spaces (
20), which add 256. - Add up the bytes as unsigned numbers, 0 to 255. Old writers summed signed bytes, −128 to 127, so readers such as Go and libarchive also work out that sum.
- Read the stored field as octal. The header is valid if it equals the sum (or the signed sum).
- A block of zeros is not a header: readers test for it before checking the sum.
GNU tar writes six octal digits, a NUL and a space. In the example
below the field is 30 31 31 35 36 34 00 20: 011564,
which is 4,980.
Magic
A GNU header has ustar and a space in magic and a space and a
NUL in version: eight bytes, 75 73 74 61 72 20 20 00, read
together as ustar, two spaces and a NUL. GNU tar’s tar.h calls
it OLDGNU_MAGIC; Go has magicGNU, versionGNU = "ustar ", " \x00".
Both GNU flavours, oldgnu and gnu, write it.
| Bytes 257 to 264 | Header |
|---|---|
75 73 74 61 72 20 20 00 | GNU tar, this format |
75 73 74 61 72 00 30 30 | POSIX ustar and pax, or star |
| all zeros | a Version 7 header, read as ustar |
libarchive’s tar(5) notes that some writers from before POSIX wrote the same eight
bytes; they are read as GNU headers. With --format=posix or
--format=ustar, GNU tar writes the POSIX magic instead, and the archive is
a ustar or pax archive.
The GNU fields
Bytes 345 to 511, from tar.h’s oldgnu_header, also given in
libarchive’s tar(5):
| Offset | Size | Name | Meaning |
|---|---|---|---|
345 | 12 | atime | The access time. tar.h: “Incr. archive: atime of the file”. Zeros in ordinary archives. |
357 | 12 | ctime | The status change time, in incremental archives. |
369 | 12 | offset | Multi-volume archives: where in the file this part starts, for an M header. |
381 | 4 | longnames | “Not used” (tar.h); tar(5): “apparently no longer used”. |
385 | 1 | unused | Padding. |
386 | 24 | sparse[0] | The first sparse map entry: offset (12 bytes, octal), then numbytes (12 bytes, octal). |
410 | 24 | sparse[1] | The second entry. |
434 | 24 | sparse[2] | The third entry. |
458 | 24 | sparse[3] | The fourth entry. |
482 | 1 | isextended | Non-zero when extension blocks with more map entries follow the header. |
483 | 12 | realsize | The full size of a sparse file. |
495 | 17 | pad | Zeros. |
The sparse fields are used only by headers of type S; see
sparse files. In an ordinary member
all of bytes 345 to 511 are zeros, unless the archive is incremental.
Example
The first header of gnu-long-path.tar, a test archive of the JavaScript
library tar-stream: a long-name entry for a 106-character path. Rows shown as
* are zeros; rows shown as … are left out. The marked bytes
are the GNU magic.
00000000 2E 2F 2E 2F 40 4C 6F 6E 67 4C 69 6E 6B 00 00 00 ././@LongLink...
*
00000060 00 00 00 00 30 30 30 30 30 30 30 00 30 30 30 30 ....0000000.0000
…
00000080 30 30 30 30 31 35 33 00 30 30 30 30 30 30 30 30 0000153.00000000
00000090 30 30 30 00 30 31 31 35 36 34 00 20 4C 00 00 00 000.011564. L...
*
00000100 00 75 73 74 61 72 20 20 00 72 6F 6F 74 00 00 00 .ustar .root...
…
L.Reading it: the name ././@LongLink; mode, uid, gid and mtime all zero;
size octal 153 at 124, which is 107 bytes, the path and a NUL; the
checksum 011564 at 148; type L (4C) at 156; the
GNU magic at 257 (0x101); the user name root at 265. The
member’s own header follows the long name’s data; see
long names.