ByteScope

XZ file format

XZ-compressed data, typically using the LZMA2 algorithm.

MIME type
application/x-xz
Extensions
.xz
Category
Archives & compression

Magic-number signature

0x00000000FD377A585A00·7zXZ·XZ magic

About the XZ format

XZ wraps LZMA2 in a container with integrity checks, giving high compression ratios for software distribution and kernel images. The six-byte magic is FD 37 7A 58 5A 00. Unlike the formats it replaced, xz is a proper container rather than a header over a stream: it has a stream header and a matching stream footer, one or more blocks each with their own header and CRC, and an index at the end listing every block's compressed and uncompressed size. That index is what lets a reader verify a file, or seek in one, without decompressing it — and it is also why a truncated .xz cannot be checked at all.

Header layout, byte by byte

OffsetLengthFieldMeaning
06Header magic bytesFD 37 7A 58 5A 00. Bytes 1 through 4 read '7zXZ' in ASCII, which is a persistent source of confusion with 7-Zip's own format; the leading FD is deliberately outside ASCII and the trailing 00 makes the file fail loudly in any text-mode transfer.
62Stream flagsThe first byte is reserved and must be 00. The low four bits of the second name the integrity check: 0 none, 1 CRC-32, 4 CRC-64, 10 SHA-256. A file written by the standard tool reads 00 04, because CRC-64 is the default.
84CRC-32 of the stream flagsLittle-endian, covering only the two bytes at offset 6. It exists so a reader can trust which check type to apply before it has decoded anything.
121Block header sizeEncoded: the real size is this value plus one, times four, so 04 means a twenty-byte block header. A 00 here is special — it means there are no more blocks and the index begins at this offset instead.
131Block flagsThe low two bits are the number of filters minus one; bit 6 says a compressed-size field follows and bit 7 an uncompressed-size field. A typical single-filter block with both sizes present reads C0.
variablevariableBlock sizes and filter flagsInside the block header, in order: the optional compressed and uncompressed sizes as multibyte variable-length integers, then the filter chain — LZMA2 is filter id 0x21 with a single property byte encoding the dictionary size — then zero padding to a multiple of four and a CRC-32 of the block header itself.
variablevariableIndexAfter the last block: a record per block giving its compressed and uncompressed size, padded to a multiple of four and followed by its own CRC-32. This is what `xz --list` reads, and it is why xz can report a file's contents without decompressing it.
-124Stream footer CRC-32Little-endian, over the six footer bytes that follow it. The footer is a fixed twelve bytes, so unlike ZIP's end record there is never any scanning backwards to find it.
-84Backward sizeLittle-endian; the real index size is this value plus one, times four. A file whose index is twelve bytes stores 02 00 00 00. It is what makes the index findable from the end of the file, and therefore what makes the whole format seekable.
-42Stream flags (copy)A byte-for-byte duplicate of offsets 6 and 7, so a decoder that started from the end learns the same check type the header declared. If the two disagree, the file has been tampered with or spliced.
-22Footer magic 'YZ'59 5A. Every intact .xz ends with these two bytes; if they are not the last two, the file is truncated, and no amount of valid-looking data at the front changes that.

Telling it apart from its neighbours

Easily confused withHow to tell
7-ZipThe confusion the format invited on itself. An .xz begins FD 37 7A 58 5A 00, in which '7z' sits at offsets 1 and 2; a real .7z has 37 7A BC AF 27 1C at offset 0. So the same two bytes appear in both, one position apart, and a sloppy search for '7z' matches both. They are unrelated formats: .7z is a multi-file archive with a directory, .xz is a single compressed stream.
lzma (LZMA_Alone)The predecessor, and the reason .lzma files are so hard to identify: they have no magic number at all. The header is thirteen bytes — one properties byte, typically 5D, then a four-byte little-endian dictionary size, then an eight-byte little-endian uncompressed size that is FF repeated when unknown. A real file reads 5D 00 00 80 00 followed by eight FF bytes, which is the closest thing to a signature it has.
GZIP1F 8B against FD 37 7A 58 5A 00, and structurally further apart than that suggests: gzip is a header over a stream with no index, while xz keeps a block index at the end and can therefore be listed and verified without decompression.
ZstandardThe modern rival. 28 B5 2F FD against xz's magic. At maximum settings xz still compresses smaller, but Zstandard decompresses several times faster and compresses far faster, which is why package managers have been migrating away.
TARA .tar.xz and an xz of a single file are the same format. Decompress and check offset 257 of the result for 'ustar' inside the first 512-byte tar header — nothing in the .xz container itself distinguishes them.

How these files break

  • Truncation. The index and the footer both live at the end, so a truncated .xz cannot be listed or verified even though every block that arrived is decodable. The tool reports an unexpected end of input, and the two-byte 'YZ' at the end of the file is the fastest way to check for it by eye.
  • A flipped bit in a block body. The default integrity check is CRC-64, so the damage is caught — but only after decompression, because the CRC-32 at offset 8 and the block header's own CRC cover metadata only. On badly damaged data LZMA2 usually fails with a decode error before reaching the checksum.
  • Stripped trailing NUL bytes. Blocks and streams are padded to multiples of four with zero bytes, so a transfer or a build step that trims trailing NULs destroys the alignment the footer depends on. The file still identifies as xz and fails at the very end.
  • Concatenated streams parsed as one. Joining .xz files is legal, optional zero padding is allowed between them, and the standard tool decompresses all of them. A hand-rolled reader that stops at the first footer magic silently drops everything after it.
  • Text-mode transfer. The 00 in the header magic is there to make this fail immediately, and it does — but the same translation applied further into the stream leaves the header intact, so the file identifies correctly and only fails when decoding reaches the damage.

Where the format stands today

XZ is what you use when a file is compressed once and downloaded a great many times, and the download is the expensive part. Kernel tarballs, distribution packages, source releases and container base layers have all leaned on it for over a decade, because at high presets LZMA2 still produces the smallest general-purpose output of the common formats. The costs are real: compression is slow and enormously memory-hungry, and decompression memory scales with the dictionary the writer chose, so an archive made at preset 9 needs about 64 MB to open — a genuine problem on embedded targets. That, plus a several-times speed gap, is why Zstandard has been steadily taking its place in package managers and filesystems since about 2019. Where xz remains first choice is bandwidth-bound distribution of static content, and it is a poor choice for anything written repeatedly or streamed live.

Open XZ 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 XZ — compare their leading bytes.

FormatFirst bytesExtension
GZIP1F 8B.gz
BZIP242 5A 68.bz2
Zstandard28 B5 2F FD.zst
7-Zip37 7A BC AF 27 1C.7z

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 XZ format? Identify it with the File Type Identifier — it reads the magic number locally, nothing is uploaded. Or browse all formats.