Status: Draft (as of September 2026). There is no compatibility guarantee yet.
SUITAR is a common-denominator, trivial-to-parse interchange format for “the result of decompressing a compressed file or unpacking an archive file”, such as ZIP, RAR, 7Z, TAR, GZIP, BZIP2, XZ, ZSTD, etc.
SUITAR is to archive files (including foobar.dat.xz compressed files as an archive containing 1 file) as Farbfeld or NIE is to image files: an uncompressed, “designed for Unix pipes” format that is trivial to read or write in a few hundred lines of code, ideally in a memory-safe programming language. It‘s a format for what the Chromium web browser’s “Rule of 2” security advice calls https://chromium.googlesource.com/chromium/src/+/master/docs/security/rule-of-2.md#normalization.
SUITAR is a subset of the well-known and widely-used TAR (Tape Archive, with GNU extensions) archive file format. Every valid SUITAR file is also a valid TAR file. These files work with popular tools like /usr/bin/tar and with popular TAR-reading libraries in a variety of programming languages.
SUITAR is a subset of “pure TAR”, not of “TAR wrapped in GZIP”, “TAR wrapped in BZIP2”, etc. A separate compression step wrapping SUITAR is feasible, just like wrapping TAR, but is out of scope of this document.
Like TAR, SUITAR files are a sequence of independent entries (files or directories). Independent means that, like JSON map keys, duplicate names are valid, although some decoders may choose to reject them.
A file‘s entry does not need to be preceded by explicit entries for that file’s parent directories.
Compared to plain TAR (and refer to the GNU TAR manual), SUITAR has further restrictions:
REGTYPE), sparse files (GNUTYPE_SPARSE) or directories (DIRTYPE). There is no support for hard links, symlinks, device files or other non-standard files.GNUTYPE_LONGNAME header block, regardless of whether the name's length is over or under 100 or 255 bytes.(1 << 53), which is 9007_199254_740992.rw-r--r--) or 0o755 (rwxr-xr-x), encoded in base-8 octal (not base-256).There is no support for various TAR variants, such as “the PAX extensions to TAR” or “the USTAR extensions to TAR”, other than what's implied by the subset of the GNU extensions that SUITAR explicitly uses.
Encoders have no meaningful choices, bar one exception. There is only one valid SUITAR encoding (unlike full TAR's backwards-compatible choice between base-8 or base-256 encoding of various sufficiently small numbers) for any given file or directory entry (its combination of type, name, size, mode, modTime and contents).
The one exception is that, if a file's contents are all NUL bytes (including zero-sized files), an encoder can choose between a REGTYPE regular file (with explicit NULs) or a GNUTYPE_SPARSE sparse file (with implicit NULs).
These rules apply to both file names and directory names.
'\n' or '\x00', the “new line” or NUL bytes.'\x7F' ASCII DEL byte."", "." or ".."."/", "./" or "../"."//", "/./" or "/../" as substrings.For example, when converting from ZIP (with Japanese file names) to SUITAR, it is the SUITAR producer‘s responsibility, not the SUITAR consumer’s, to detect and transform Shift-JIS encoded names to equivalent and valid UTF-8.
SUITAR files are a sequence of entries, followed by a 1024-byte “End Of File” marker. The EOF marker's bytes are all NUL. Each entry occupies an integer number of 512-byte blocks:
GNUTYPE_LONGNAME header block.REGTYPE, GNUTYPE_SPARSE or DIRTYPE header block.REGTYPE, 0 or more payload blocks containing the file contents.REGTYPE, no further blocks.Like all blocks, each header block is 512 bytes long. Each header block also starts with a 12-byte magic signature (that is not valid UTF-8), identifying SUITAR version 1. There are no other versions at this time.
The first 384 out of 512 bytes must match this template (arranged as 24 rows of 16 bytes per row, plus commentary):
@@@@@@@@@@@@.... @@@@@@@@@@@@ = "\x13sUItAR\x00\xFE\xFDv1". ................ ................ ................ ................ ................ ....0000???.0177 ??? = mode. 776.0177776.$... ????????$...???? ???????? = physical size, ???????? = modTime. ??????????. ?... ?????? = checksum, ? = type. ................ ................ ................ ................ ................ ................ .ustar .nobody. ................ .........nobody. ................ ................ ................ ................ ................
In this template, @ indicates the magic signature, . indicates a 0x00 NUL byte, $ indicates a 0x80 byte and ? indicates parts of the template that are variable, not hard-coded.
These ? bytes are the 3-byte mode ("644" or "755"), physical size or modTime as an 8-byte big-endian uint64, 6-byte checksum (see below) or 1-byte type, which must be one of:
'0' for REGTYPE.'5' for DIRTYPE, in which case mode must be "755" and physical size must be all zeroes.'L' for GNUTYPE_LONGNAME, in which case mode must be "644" and modTime must be all zeroes.'S' for GNUTYPE_SPARSE, in which case physical size must be all zeroes and offset and logical size (see below) must be the same number and, again, within the half-open range 0 .. (1 << 53).The last 128 out of 512 bytes (8 rows of 16 bytes per row) must be all NUL bytes unless the type is GNUTYPE_SPARSE, in which case it must match this template (and ? again indicates an 8-byte big-endian uint64):
..$...????????$. ???????? = sparse offset. ................ ................ ................ ................ ................ ...$...????????. ???????? = sparse logical size. ................
A 512-byte header block's checksum value is simply the sum of each byte (after converting from uint8 to uint32, to avoid overflow) in the block, at offsets in the two half-open ranges 0 .. 148 and 156 .. 512, which excludes the 8 bytes for the 6-byte checksum itself plus another two hard-coded bytes "\x00\x20".
That checksum value is written as a 6-byte ASCII octal number in the header. For example, 4853 (decimal) would be encoded as "011365" (octal).
Each entry has one or more payload blocks, between its two header blocks, containing the file or directory name. The name length (including a trailing NUL byte) is the first header block‘s physical size value, and must be within the half-open range 2 .. 4096, and so the excluding-a-trailing-NUL length must range within 1 .. 4095. Rounding up that including-a-trailing-NUL length to a multiple of 512 gives the number of 512-byte payload blocks that contain the name. All padding bytes in the name’s final payload block must be NUL.
For REGTYPE entries, the second header block‘s physical size value gives the reconstructed file’s size and rounding that up to a multiple of 512 gives the number of 512-byte payload blocks that contain the file contents. Again, all padding bytes in the contents' final payload block must be NUL.
For other entries (DIRTYPE or GNUTYPE_SPARSE), there are no further payload blocks after the second header block.
For GNUTYPE_SPARSE entries, the second header block‘s logical size value gives the reconstructed file’s size and its contents are all NUL bytes.
The google/wuffs repository, which holds this specification document, also holds a suitar Go package and some test/data/*.suitar example files, readable by that Go package but also by /usr/bin/tar.
Updated on September 2026.