ByteScope

GZIP file format

Gzip-compressed data, typically wrapping a single file or a tarball.

MIME type
application/gzip
Extensions
.gz
Category
Archives & compression

Magic-number signature

0x000000001F8B··gzip magic

About the GZIP format

Gzip compresses a single stream with DEFLATE and is the backbone of HTTP compression and the ubiquitous .tar.gz. Files start with the two magic bytes 1F 8B. The format is deliberately tiny — a ten-byte fixed header, a few optional fields, the deflate stream, and an eight-byte trailer — and deliberately streamable: nothing in it needs to be known before compression starts, and nothing at the end needs seeking back to fix up. That is also its limit. There is no directory, no per-file structure and no way to reach the middle of the data without decompressing everything before it.

Header layout, byte by byte

OffsetLengthFieldMeaning
02Magic ID1 ID21F 8B. Neither byte is printable ASCII, which was intentional: a gzip stream must not look like text to a mail gateway or a terminal that might try to be helpful with it.
21Compression method (CM)8, meaning deflate. Values 0 through 7 are reserved and none has ever been assigned, so in practice any byte other than 08 here means the file is not gzip or the header is damaged.
31Flags (FLG)Bit 0 FTEXT (the content is probably text), bit 1 FHCRC (a two-byte header CRC follows), bit 2 FEXTRA, bit 3 FNAME (a NUL-terminated original file name follows), bit 4 FCOMMENT. A file compressed by the command-line tool normally reads 08, because it stores the name.
44Modification time (MTIME)Little-endian Unix seconds of the original file, or 0 when unavailable. It is why gzipping the same input twice produces different bytes, and why reproducible builds pass a flag to zero it.
81Extra flags (XFL)With deflate, 2 means the slowest and best compression was used and 4 means the fastest; 0 otherwise. It is advisory only — no decompressor does anything with it.
91Operating system (OS)The filesystem the original came from: 0 FAT, 3 Unix, 11 NTFS, 255 unknown. It leaks where a file was built, which is another field reproducible builds normalise.
10variableOptional fields, then the deflate streamWhichever flag bits were set, in a fixed order: extra field (a two-byte length then that many bytes), original file name, comment, header CRC-16. A file storing the name 'payload.bin' spends offsets 10 to 21 on it, and deflate begins at 22.
-84CRC-32 of the uncompressed dataLittle-endian, computed over the original bytes rather than the compressed ones. This is what `gzip -t` checks and what a truncated file can never satisfy.
-44ISIZELittle-endian original size modulo 2^32. A 200000-byte input ends 40 0D 03 00. Being 32-bit, it silently wraps above four gigabytes, which is why `gzip -l` reports nonsense for very large files and why it must never be trusted as an allocation size.

Telling it apart from its neighbours

Easily confused withHow to tell
zlibThe pair that actually catches people out, because both wrap the same deflate stream. A zlib stream has a two-byte header instead of ten — in practice 78 01, 78 9C or 78 DA — and ends with an Adler-32 rather than a CRC-32. There is no magic number, no name and no length, so a zlib blob renamed .gz opens nowhere and a gzip fed to a zlib decoder fails immediately.
raw deflateRaw deflate as defined by RFC 1951 has no header and no trailer at all — it starts straight into the first block's three bits. It is what a ZIP entry stores and what HTTP's `Content-Encoding: deflate` ambiguously meant, and it is the reason so many HTTP clients try zlib first and fall back to raw.
TARA .tar.gz and a gzip of one ordinary file are the same format; only the content differs. Decompress and look at offset 257 of the result — a tar has 'ustar' there, inside the first 512-byte member header. Cheaper still, the FNAME field at offset 10 usually admits it by ending in .tar.
ZIP1F 8B against 50 4B 03 04, and structurally further apart than the shared word 'compressed' suggests: a ZIP has a central directory at the end and can list and extract one entry without touching the rest, whereas a gzip stream must be read from the beginning to reach anything.
BZIP2'BZh' plus a digit against 1F 8B. Both are single-stream Unix compressors used the same way and named almost interchangeably in build scripts, so the extension is often wrong; the first two bytes never are.

How these files break

  • Truncated download. The eight-byte trailer is gone, so the decompressor emits everything it can decode and then reports an unexpected end of file. The recovered bytes are normally sound — the failure is that nothing can confirm it, because both the length and the checksum lived in the missing tail.
  • A flipped bit inside the deflate stream. The output length is right and the CRC-32 at offset -8 does not match, which is precisely the case `gzip -t` exists to name. Depending on where the bit landed, decompression may also fail outright with an invalid distance or code-length error rather than reaching the checksum at all.
  • Text-mode transfer. Line-ending translation rewrites 0D 0A to 0A inside compressed data, and the ten-byte header survives untouched, so the file still identifies as gzip and still reports its original name before failing partway through the stream.
  • Multi-member archives read as one. Concatenating gzip files is legal and a conforming decompressor emits all of them joined, but a hand-rolled parser that reads the first ISIZE and stops silently drops everything after the first member. Parallel compressors produce exactly this shape.
  • ISIZE trusted as a size. Above four gigabytes it wraps, so a program that allocates a buffer from it under-allocates by a whole multiple of 4 GiB. It is a header field describing the data, not a promise, and it is not covered by any checksum.

Where the format stands today

Gzip is the most-executed compression format in the world and shows no sign of moving. Every HTTP stack still negotiates it, .tar.gz is the default source-release shape on Unix, log rotation writes it, and every language ships a decoder in its standard library — so it remains the safe answer whenever the reader is unknown. On ratio it lost long ago: bzip2, xz and Zstandard all beat it, and on the web Brotli beats it for static text while Zstandard beats it on speed at similar ratios. What keeps gzip first choice is universality plus streaming: it needs no seeking, no temporary file and no knowledge of the input length, so it works in a pipe, in a socket and in a firmware image. It is the wrong choice whenever you need to reach one file inside a collection, because there is no index — that is what ZIP is for.

Open GZIP files on this site

Every one of these runs in your browser — the file never leaves your machine.

Related formats

Formats that are easy to confuse with GZIP — compare their leading bytes.

FormatFirst bytesExtension
TAR75 73 74 61 72.tar
ZIP50 4B 03 04.zip
BZIP242 5A 68.bz2
XZFD 37 7A 58 5A 00.xz
Zstandard28 B5 2F FD.zst

Frequently asked questions

What is a magic number in a file?

The first few bytes of a file, which identify its format regardless of what the name says. A PNG always starts with 89 50 4E 47; a ZIP with 50 4B 03 04. Operating systems, browsers and the file command all read these bytes rather than trusting the extension, which is why renaming a file does not change what it actually is.

How do I check a file's magic number myself?

On macOS or Linux, xxd -l 16 yourfile prints the first 16 bytes; on Windows, Format-Hex -Path yourfile -Count 16 in PowerShell. Or drop the file into the File Type Identifier on this site, which reads the bytes locally and names the format for you — nothing is uploaded.

Why do two formats share the same magic number?

Because one is built on the other. Every docx, xlsx, pptx, apk, jar and epub begins with the ZIP signature, since all of them are ZIP archives underneath; telling them apart means looking at the entries inside. Java class files and macOS universal binaries both start with CA FE BA BE and are distinguished by the field that follows.

Can a file have no magic number at all?

Yes. Text-based formats — XML, HTML, JSON, SVG, CSV — have no fixed byte signature, so they are recognized structurally instead: a leading <?xml declaration, a <svg element, or a { followed by a quoted key. That detection is a good guess rather than a certainty, which is why this reference marks those formats as probe-detected.

Does a matching magic number mean the file is safe?

No. It tells you what the format is, not whether the contents are harmless — a genuine PDF or docx can still carry a malicious payload. Identifying the true type is a useful first check, especially when the extension disagrees with the bytes, but it is not a malware scan.

Have a file that might be in the GZIP format? Identify it with the File Type Identifier — it reads the magic number locally, nothing is uploaded. Or browse all formats.