$MFT is the index NTFS uses to keep track of every file and directory on a volume. It is also the single most informative artifact you can pull from a Windows machine. Every other file on the volume, the table itself included, has at least one record inside it. Forensic tools answer hard questions about files Windows no longer admits exist because the records survive deletion. Threat hunters chase persistence through it because attackers cannot move files on NTFS without writing to it. If you only ever learn one Windows artifact at the byte level, this is the one to learn.
This is the reference I wish I had when I started. It covers what the table is, what a record looks like, which attributes a record can carry, what the reserved system files at the start mean, what the dreaded "Windows cannot recover the master file table" error actually means, and how to read the table yourself.
What is the Master File Table
$MFT is a file. A single file. It sits at a known offset near the start of every NTFS volume. The boot sector at offset 0 of the partition (the 512 bytes of the BIOS Parameter Block) contains a field called MftStartLcn that points to the first cluster of $MFT. Read those 1,024 bytes and you have record 0, the table's self-description.
Each row of the table is exactly 1,024 bytes and describes one file or one directory. Every record holds the name, timestamps, DOS-style flags, security descriptor reference, and either the data itself (small files) or a list of disk clusters where the data lives (large files), all encoded as a sequence of typed attributes.
NTFS was introduced with Windows NT 3.1 in 1993 and has been the default Windows filesystem on every fixed disk since Windows XP. It replaced FAT, which keeps a small allocation table and stores filenames inside directory entries. NTFS puts almost every piece of metadata about every file into one structured table, $MFT. That design has two consequences worth committing to memory:
- All metadata is in one place. A single seek to
$MFTenumerates every file on the volume. This is why forensic tools, antivirus engines, indexing services, and backup software all read it. It is also why a corrupted$MFTis a much bigger problem than a corrupted FAT. - Deleted files leave their metadata behind. When NTFS deletes a file, it clears one bit in the record header and marks the file's clusters as free in
$Bitmap. The rest of the record (name, timestamps, often the data) stays put until that record slot is reused. See what survives a delete.
The acronym MFT stands for Master File Table. Written $MFT on disk because, on NTFS, the dollar sign prefixes the names of metadata files.
How $MFT is laid out on disk
When NTFS formats a volume it reserves a region called the MFT zone near the start of the partition. The first 16 records of the table are reserved for NTFS metadata files (described below); record 0 is the table's own entry, pointing back at its own clusters.
$MFT grows by extending into its reserved zone whenever it needs more records. If the volume fills up before the zone is exhausted, Windows shrinks the zone to make room for user data, which is why a heavily-fragmented $MFT is common on aging filesystems. The table never shrinks. Once a slot has been created, it stays in $MFT; deletion only clears the in-use flag. That is why old deleted records far above the current high-water mark can survive for years on a lightly-used volume.
A backup of the first records lives in $MFTMirr, placed in the middle of the volume. If $MFT itself is unreadable, NTFS uses $MFTMirr to bootstrap recovery. See $MFTMirr and when NTFS uses it.
Anatomy of a FILE record
Every MFT record begins with the four-byte ASCII signature FILE (46 49 4C 45). Corrupt records carry BAAD instead, a tombstone written by chkdsk when it could not repair the record. After the signature comes a 56-byte header, then the fixup array, then a stream of typed attributes terminated by 0xFFFFFFFF.
The header carries the fields you reach for most often:
- Signature.
FILEfor a valid record,BAADfor unrepairable. - Update sequence (fixup) array. The torn-write detection trick. The last two bytes of every 512-byte block in the record are replaced with a USN; the originals are stashed in this array. On read, NTFS verifies the USN and restores the original bytes.
$LogFilesequence number. A pointer into$LogFilefor crash recovery.- Sequence number. Incremented every time the record slot is reused. Combined with the record number it forms the 64-bit file reference that uniquely identifies one particular incarnation of a file.
- Hard link count. Number of
$FILE_NAMEattributes pointing at the record. - Flags. Bit 0 is
IN_USE(clear means deleted). Bit 1 isDIRECTORY. - Base file record reference. Non-zero on extension records that belong to a base record elsewhere in the table.
- Used and allocated size. Used is how much of the 1,024-byte slot this record actually consumes; allocated is the slot size (always 1,024 on standard volumes).
For a byte-by-byte walk through the header and the attribute stream, see inside an MFT record.
After the header come the attributes. Each one has its own short header (type, length, resident/non-resident flag, optional name) followed by the data. There is no fixed order, but in practice $STANDARD_INFORMATION is first and $DATA last. A record that runs out of space (too many fragments, too many ADS, an unusually long name) sprouts an $ATTRIBUTE_LIST attribute pointing at one or more extension records elsewhere in the table. Parsers must follow the chain to reconstruct the file.
File attributes stored in $MFT
This is the canonical list of NTFS attribute types, with hex codes:
| Type | Hex | Purpose |
|------|-----|---------|
| $STANDARD_INFORMATION | 0x10 | Four timestamps (created, modified, accessed, MFT-modified), DOS flags, owner ID, security ID, USN pointer. |
| $ATTRIBUTE_LIST | 0x20 | Pointers to extension records when a file's attributes overflow one record. |
| $FILE_NAME | 0x30 | One filename, parent directory reference, allocated and real size, and a second set of four timestamps. A file may have several (one per hard link, plus the 8.3 short name on volumes with that enabled). |
| $OBJECT_ID | 0x40 | 128-bit object identifier used by the Distributed Link Tracking service. |
| $SECURITY_DESCRIPTOR | 0x50 | Legacy per-file ACL. Modern NTFS stores ACLs centrally in $Secure and references them by ID from $STANDARD_INFORMATION. |
| $VOLUME_NAME | 0x60 | Only on record 3 ($Volume). Holds the volume label. |
| $VOLUME_INFORMATION | 0x70 | NTFS version, dirty flag. |
| $DATA | 0x80 | The file's contents. Resident for very small files; non-resident (a runlist of clusters) otherwise. A file can carry several $DATA attributes; the unnamed one is the primary stream, named ones are alternate data streams. |
| $INDEX_ROOT | 0x90 | Root of a B+ tree. Used by directories ($I30), reparse-point indexes, and other indexed structures. |
| $INDEX_ALLOCATION | 0xA0 | Non-resident continuation of a large index. |
| $BITMAP | 0xB0 | Allocation bitmap for $MFT itself or for large directories. |
| $REPARSE_POINT | 0xC0 | Symlinks, junctions, mount points, OneDrive placeholders, dedup stubs. |
| $EA_INFORMATION / $EA | 0xD0 / 0xE0 | OS/2-era extended attributes. Rare on modern Windows. WSL1 used them for POSIX metadata, which is the only context worth caring about. |
| $LOGGED_UTILITY_STREAM | 0x100 | EFS encryption metadata ($EFS), TxF transaction data. |
A record always carries at least $STANDARD_INFORMATION, one $FILE_NAME, and one $DATA. Everything else is optional and feature-driven.
Resident vs non-resident data
Most $DATA attributes on a real volume are non-resident: the attribute header carries a compact list of cluster runs (a starting LCN plus a length, repeated), and the file's bytes live elsewhere on the disk. The attribute header itself is small.
If the file is small enough (typically under ~700 bytes once the other attributes are accounted for), NTFS stores the bytes inline inside the record. That is resident data, and it is one of the most useful artifacts in forensic work: the contents of a small text file deleted weeks ago may still sit, byte-for-byte, inside an unallocated $MFT record. See resident data for the size threshold and what to look for.
NTFS metadata files in the first sixteen records
The first 16 records of $MFT are reserved for NTFS's own bookkeeping. They start with a $ so they do not collide with user filenames. The ones worth knowing:
| Rec # | File | What it is |
|-------|------|------------|
| 0 | $MFT | The table itself. Its $DATA runlist points at its own clusters. |
| 1 | $MFTMirr | Partial backup of the first records of $MFT. |
| 2 | $LogFile | Transaction log used to undo or redo incomplete operations after a crash. |
| 3 | $Volume | Volume label and dirty flag. |
| 4 | $AttrDef | Schema of valid attribute types. |
| 5 | . | The root directory. |
| 6 | $Bitmap | One bit per cluster on the volume; tracks allocation. |
| 7 | $Boot | Copy of the boot sector. |
| 8 | $BadClus | Sparse file whose runs point at every cluster the filesystem has marked bad. |
| 9 | $Secure | Central store of security descriptors. |
| 10 | $UpCase | Unicode upper-case mapping table used for case-insensitive name comparison. |
| 11 | $Extend | Directory containing newer system files: $ObjId, $Quota, $Reparse, $UsnJrnl, $RmMetadata. |
The change journal $UsnJrnl (under $Extend) is especially useful in forensics; it logs every metadata change on the volume and complements $MFT for timeline reconstruction. See pairing journal with file table.
When $MFT goes wrong
The error "Windows cannot recover master file table. CHKDSK aborted" appears when chkdsk cannot read $MFT and cannot fall back to $MFTMirr either. By that point NTFS has already tried and failed at its built-in self-repair. The root causes I have seen, ranked by how often they actually turn out to be each one:
- Failing physical media. Bad sectors in the MFT zone return garbage on read. SMART data usually corroborates. Image the disk with
ddrescue, notdd, and work on the image. - Sudden power loss during a metadata-heavy operation. The transaction log normally rolls these back, but a corrupted
$LogFiledefeats the rollback. - Driver- or filter-level corruption. Misbehaving disk encryption stacks, file system minifilters, or buggy storage drivers can write inconsistent records. Common on hosts with multiple security agents fighting each other.
- Malicious overwrites. Wipers and a handful of ransomware families (notably Petya and the early NotPetya wave) deliberately scribble on
$MFTto make the volume unmountable. See ransomware patterns in MFT.
The forensically sound response:
- Stop writing to the volume immediately. Every further write reduces the chance of recovery.
- Image the disk with FTK Imager,
dd, orddrescueto a known-good destination. Verify the hash. - Work on the image, not the original. Try
testdisk,R-Studio, or a manual parse that findsFILErecords by signature scanning the volume directly. Even if the on-disk pointer to$MFTis gone, the records themselves are usually still recognizable. - If the goal is to bring the volume back online rather than to recover data, only then run
chkdsk /fon the image.
chkdsk /b on a writable volume can clear bad-cluster markers, but it can also discard records it cannot understand. Run it on the original only after you have an image and have decided availability beats forensic fidelity.
How to read $MFT
You have three realistic options:
- MFTECmd (Eric Zimmerman). A Windows CLI that produces CSV in the bodyfile-friendly layout most timeline tools expect. The de facto standard for incident responders.
omerbenamram/mft. A Rust crate and CLI (mft_dump). The parser this site uses, useful when you want to script analysis or embed it in a larger pipeline.- This site's browser parser. Drop
$MFTonto the homepage and it runs the same Rust parser, compiled to WebAssembly, entirely in your browser. Nothing is uploaded.
For a comparison with concrete pros and cons, see MFT parser tools. For practical workflows on a parsed $MFT, see building a timeline, deleted files, and extracting $MFT.
Frequently asked questions
What does MFT stand for?
MFT stands for Master File Table. Written $MFT on disk because, on NTFS, the dollar sign prefixes the names of metadata files.
What is the master file table used for?
It is the index NTFS uses to find every file and directory on a volume. Each entry stores the file's name, timestamps, security information, attributes, and the location of its data on disk.
What file attributes are stored in the master file table?
At minimum every record carries $STANDARD_INFORMATION (timestamps, DOS flags), $FILE_NAME (name and a second set of timestamps), and $DATA (the file's contents or a pointer to them). Records can also carry $ATTRIBUTE_LIST, $OBJECT_ID, $SECURITY_DESCRIPTOR, $INDEX_ROOT, $INDEX_ALLOCATION, $BITMAP, $REPARSE_POINT, $EA, and $LOGGED_UTILITY_STREAM depending on the file. The full reference is in the attributes table above.
How big is the master file table?
Each record is 1,024 bytes. The table reserves about 12.5% of the volume by default (the MFT zone) but only consumes the space it actually needs. A volume with a million files has roughly a 1 GB $MFT.
Is $MFT the same as $MFTMirr?
No. $MFTMirr is a partial backup of the first few records of $MFT, placed elsewhere on the disk so NTFS can bootstrap recovery if the main table's header is corrupted.
How do I fix a corrupt master file table?
Image the disk first. Then either run chkdsk /f against the image (fast, may discard records), or use a recovery tool that can scan for FILE signatures and reassemble the table from raw clusters (slow, preserves more evidence). Never run chkdsk against the original volume before imaging.
Can I read $MFT on Linux or macOS?
Yes. $MFT is just a file. Any parser that accepts a raw $MFT dump works on any OS: omerbenamram/mft, analyzeMFT, this site's browser tool. You only need Windows to extract the file from a live mounted volume.
Further reading
- Microsoft, Master File Table. The official, terse reference.
- Brian Carrier, File System Forensic Analysis. Still the best single book on NTFS layout and recovery.
- The linux-ntfs project's NTFS Documentation. Field offsets for every attribute, reverse-engineered the hard way.