Matroska file format
Matroska, an open multimedia container supporting nearly any codec.
- MIME type
- video/x-matroska
- Extensions
- .mkv
- Category
- Video
Magic-number signature
| 0x00000000 | 1A45DFA3 | ·E·· | EBML header |
The EBML DocType string near the start reads 'matroska'.
About the Matroska format
Matroska is the open container that set out to hold anything: any video codec, any audio codec, an arbitrary number of subtitle tracks, chapters, attachments, tags and per-track languages, all in one file. It is built on EBML, a binary encoding shaped like XML in which every element is a variable-length identifier followed by a variable-length size and then either a value or nested elements. Because sizes are declared rather than implied, a Matroska file can be walked without understanding a single element in it, and a reader can skip whatever it does not know. WebM is the same encoding with a smaller codec list, so the two are identical for their first twenty-one bytes and differ only in the DocType string that names the format.
Header layout, byte by byte
| Offset | Length | Field | Meaning |
|---|---|---|---|
| 0 | 4 | EBML master element ID | 1A 45 DF A3, the magic number, and the only field in the file at a position fixed by the specification rather than by convention. WebM has exactly the same four bytes here. |
| 4 | 1 | EBML header size | A variable-length integer whose leading 1 bit marks it one byte long, the remaining seven bits giving the size of the header body. A3 is 35 in a Matroska file against 9F, 31, in a WebM one — the four-byte difference is the length of 'matroska' minus 'webm'. Writers are allowed to pad this integer to as many as eight bytes. |
| 5 | 4 | EBMLVersion element | 42 86 81 01 — element ID, a size of 1, and the value 1. Every element in this header carries a default and may legally be omitted, so the offsets below describe what ordinary writers emit rather than a layout the specification guarantees. |
| 9 | 4 | EBMLReadVersion element | 42 F7 81 01. The minimum EBML version a reader must implement to parse the file. It has never moved off 1. |
| 13 | 4 | EBMLMaxIDLength element | 42 F2 81 04. The longest element identifier used anywhere in this file, four bytes in practice, which lets a parser fix its buffer sizes before it starts. |
| 17 | 4 | EBMLMaxSizeLength element | 42 F3 81 08. The longest size field in the file. Eight is the usual value, and it is what makes the unknown-size marker on a live-written Segment eight bytes wide. |
| 21 | 2 | DocType element ID | 42 82. Names the EBML-based format the file actually is, and the single reason a Matroska file cannot be distinguished from a WebM one by its first twenty bytes. |
| 23 | 1 | DocType length | 88 — a one-byte variable-length integer holding 8, the length of the string that follows. WebM reads 84 here for its four-character name, and every offset after this point differs by four between the two formats. |
| 24 | 8 | DocType value | 6D 61 74 72 6F 73 6B 61, the ASCII letters matroska. This is the field that decides the format, and the reason a file-type check has to read at least thirty-two bytes rather than four. |
| 32 | 4 | DocTypeVersion element | 42 87 81 04. Which revision of the Matroska element set the writer used — 4 covers the additions most current muxers rely on. A reader is expected to skip unfamiliar elements rather than reject the file. |
| 36 | 4 | DocTypeReadVersion element | 42 85 81 02. The minimum revision needed to parse the file at all, which is deliberately lower than the version above so older readers are not locked out. |
| 40 | 4 | Segment element ID | 18 53 80 67, the master element containing the entire body of the file: track definitions, clusters of frames, the cue index, chapters, tags and attachments. Its size follows immediately, and it is the unknown-size form in a file still being written. |
Telling it apart from its neighbours
| Easily confused with | How to tell |
|---|---|
| WebM | The same encoding with a different name at offset 24: 'matroska' against 'webm'. The tell one byte earlier is quicker — the DocType length at 23 is 88 here and 84 there — and the EBML header size at offset 4 differs for the same reason, A3 against 9F. Codecs are what actually matter: Matroska carries H.264, HEVC, AC-3, DTS and TrueHD, none of which a browser will decode from a WebM-labelled file. |
| MKA | An .mka is a Matroska file holding only audio, .mks only subtitles, and .mk3d a stereoscopic one. Not one of them has a distinguishing header byte — the DocType reads 'matroska' in every case — so the extension is the writer's claim about the content and the Tracks element is the only place the truth is recorded. |
| MP4 | Structurally unrelated: MP4 is a tree of boxes with big-endian 32-bit sizes and 'ftyp' at offset 4, while Matroska is EBML with variable-length identifiers and sizes and its magic at offset 0. They are compared constantly because both can hold H.264 and AAC, and remuxing between them is a lossless copy, but nothing about their bytes is shared. |
| AVI | The container Matroska was built to replace. AVI is RIFF with little-endian sizes, starting 52 49 46 46 and 'AVI ' at offset 8, and it has no proper support for variable frame rate, modern audio, subtitles or per-track language. A file remuxed from AVI into MKV keeps the same compressed frames and gains all of that. |
How these files break
- An unknown Segment size that was never patched. A muxer writing to a pipe or a live source sets every value bit of the Segment size integer, the all-ones form EBML defines for exactly this case, and is supposed to go back and write the real length when it finishes. Killed partway through, it never does — leaving a file that plays from the beginning, reports no duration and cannot seek.
- A missing Cues element. The seek index normally goes at the head or the tail of the Segment and is simply absent from anything captured live. Players fall back to scanning clusters, which is slow and inexact on a large file; a straight remux writes a proper index without recompressing a frame.
- Truncation. Every element states its own length, so a reader walks cleanly to the last complete cluster and then meets a size promising bytes that do not exist. Some players show everything up to that point and stop; others call the whole file corrupt, which is why a partly downloaded MKV opens in one tool and not another.
- Subtitle text in the wrong encoding. The container records a CodecID and a language per track but not, for the older text formats, a reliable character encoding. A subtitle track written in Big5, GBK or Shift-JIS and read as UTF-8 comes out as mojibake while every byte of video and audio is perfect.
- A damaged element identifier. Because identifiers and sizes are both variable length, one flipped byte in a size field can make a parser jump into the middle of a frame and read garbage as the next element. The file often still plays, because clusters resynchronise, but a strict parser stops at the point of the flip and reports everything after it as unreadable.
Where the format stands today
Matroska is where video goes to be kept rather than delivered. Anything with multiple audio languages, several subtitle tracks, chapters and attached fonts is an MKV, because no other container handles that combination without argument, and remuxing into it is a lossless copy of the frames rather than a re-encode. It is also the working format of most encoding tools, which is why files from them arrive as .mkv even when the contents would fit an MP4 perfectly. Where it loses is reach: no browser plays it, iOS and most televisions refuse it, and hardware players support it unevenly enough that the safe answer for anything being sent to someone else is still MP4. The usual pattern is to archive in Matroska and export to MP4, and because the video inside is untouched, that export is a container swap rather than a quality loss.
Open Matroska 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 Matroska — compare their leading bytes.