> Where you are: Part II, Chapter 10 of 40. Chapters 6–9 recovered data from single volumes — deleted files (Ch.6), carved fragments (Ch.7), mechanically failed platters (Ch.8), and TRIM-limited flash (Ch.9). RAID multiplies the problem across many...
In This Chapter
- When one disk is not the whole story
- The six parameters that define every array
- How each RAID level fails
- Parity rotation: left, right, synchronous, asynchronous
- Virtual RAID reconstruction: rebuilding the array without the controller
- Recovery technique: from raw members to recovered files 💾
- Forensic technique: the array as evidence 🔍
- Tool demonstration
- Worked example: a four-disk RAID 5 after a controller death
- The most common RAID disaster: the forced rebuild
- Common mistakes
- Limitations: knowing when to stop
- Progressive project: when your case source is an array
- Summary
Chapter 10: RAID Recovery — Rebuilding Arrays and Recovering from Multi-Disk Failures
Where you are: Part II, Chapter 10 of 40. Chapters 6–9 recovered data from single volumes — deleted files (Ch.6), carved fragments (Ch.7), mechanically failed platters (Ch.8), and TRIM-limited flash (Ch.9). RAID multiplies the problem across many disks at once: lose the controller, or one disk too many, and your data is scattered, interleaved, and parity-encoded across the survivors. This chapter teaches you to rebuild the array in software, from the bare disks, without the original hardware — and to recognize the single most common way RAID arrays are destroyed by the people trying to save them.
Learning paths: 💾 Data Recovery lives here — multi-disk arrays are daily bread for any recovery shop, and the failure modes are predictable. 🔍 Forensic Examiners must reconstruct seized server arrays reproducibly and image every member under chain of custody. 🛡️ Incident Response meets RAID whenever a crashed or ransomware-hit server must be brought back. 📜 Legal/eDiscovery: a reconstructed volume is a derived exhibit — its parameters must be defensible to another examiner.
When one disk is not the whole story
A four-bay NAS sits under the reception desk of a small architecture firm. It holds eight years of drawings, contracts, renderings, and the only copies of three buildings currently under construction. One Monday the amber light is on, the web console says "Volume degraded — Disk 2 failed," and the office manager does the natural thing: orders a replacement drive, slots it in Friday afternoon, and clicks Repair. By Saturday morning the volume is gone. The console now says "Volume crashed," every share is offline, and the most recent backup is a USB drive someone last rotated four months ago.
This is not a story about a bad drive. It is a story about a system — about how data that no single disk contains can vanish even though most of the disks are still perfectly readable. The firm's drawings are still there, on the platters, in tens of millions of sectors. But they are no longer files. They are strips of bytes interleaved across four members, some of them parity, organized by a controller that is now confused, in an order and geometry that the recovery technician must rediscover from scratch.
RAID — a Redundant Array of Independent Disks — was invented in 1987 (Patterson, Gibson, and Katz at Berkeley) to do two things at once: make storage faster by spreading I/O across many spindles, and make it more reliable by storing enough redundancy to survive a disk failure. Both goals are achieved by spreading data across disks, and that spreading is exactly what makes recovery hard. On a single drive (Chapters 6–9) the file system tells you where a file lives. On a RAID array, the file system describes a logical volume that does not physically exist on any one disk — it is an emergent property of how the members are combined. Recover the wrong combination and you get garbage that looks like data: the right bytes in the wrong order.
The anatomy of RAID controllers, arrays, and the disks inside them was introduced in Chapter 3 — Storage Technology. This chapter is about what happens after the array breaks: how each level fails, how to reconstruct an array virtually without its controller, which tools do it, and the disaster that lands the most arrays on a recovery bench — the forced rebuild of a degraded array. Throughout, two principles from Chapter 5 dominate everything else: image first, reconstruct second, and never, ever, work on the originals. Nowhere in this book are those rules more expensive to break.
Why This Matters. RAID protects you from disk failure. It does not protect you from deletion, corruption, fire, theft, ransomware, accidental reformat, controller failure, or human panic. People conflate "redundant" with "backed up," and the conflation is catastrophic precisely because RAID works so well for so long that the absence of a real backup is invisible — until two disks are down at once and the array is the only copy. (Theme 6: behind every dead array is someone who thought they were safe.)
The six parameters that define every array
Before we look at how each level fails, fix this mental model: every striped array is fully described by six parameters. Virtual reconstruction is nothing more than discovering all six and feeding them to a tool. Forget any one and the volume will not mount, or worse, will mount as plausible-looking corruption.
THE SIX UNKNOWNS OF A RAID ARRAY
1. Member set Which physical disks belong? Is one missing/stale/dead?
2. Disk order The sequence members occupy in the stripe (NOT bay order!)
3. Strip size Bytes per chunk on one disk before moving to the next
(a.k.a. "block size" / "chunk size" / loosely "stripe size")
4. Parity layout For RAID 5/6: rotation direction + symmetry, and which
disk holds parity for stripe 0
5. Start offset Where array DATA begins on each member (metadata may sit
at the start or the end of the disk)
6. Special rules Parity delay, mdadm near/far/offset, hot-spare slots,
nested levels (10/50/60), reshape-in-progress
A note on vocabulary, because the industry is sloppy and the sloppiness causes mistakes. A strip (or chunk) is the contiguous block written to one disk before the controller moves to the next disk. A stripe is the full horizontal row — one strip from every disk at the same physical offset. Many tools and admins say "stripe size" when they mean the per-disk strip size; others mean the full-stripe width (strip × number of data disks). When a vendor says "256 KB stripe," confirm which they mean before you trust it — a factor-of-N error here guarantees a failed reconstruction. In this chapter, strip always means the per-disk chunk.
Try This. Before you ever touch a damaged array, build a healthy one you can break safely. On a Linux box, create four 256 MB image files, attach them as loop devices, and
mdadm --createa RAID 5 across them (commands appear later in this chapter and in Appendix J). Copy in a few known files, thenmdadm --stopand try to reconstruct it from the raw images with a tool, pretending you don't know the parameters. You will internalize the six unknowns in an afternoon.
How each RAID level fails
The recovery strategy is dictated entirely by the level, because the level dictates how much redundancy exists and therefore how many members you can lose. Get the level wrong and every other decision is wrong.
RAID 0 — striping with no net
RAID 0 splits data into strips and writes them across all members in turn, with no parity and no redundancy. Two disks, strip size s:
RAID 0 (2 disks, no redundancy) capacity = N x smallest disk
+-----------+-----------+
strip | Disk 0 | Disk 1 |
0..1 | A1 | A2 | A file is sliced A1 A2 A3 A4 ...
2..3 | A3 | A4 | and laid left-to-right, top-to-bottom.
4..5 | A5 | A6 |
+-----------+-----------+
Lose EITHER disk and every file larger than one strip has holes.
The failure mode is total and unforgiving: one dead disk means the array is gone. There is no parity to fill the gap. A 200 KB JPEG on a 64 KB-strip two-disk RAID 0 has its 1st, 3rd, 5th... strips on one disk and its 2nd, 4th, 6th... on the other; lose one disk and every other 64 KB of the file is missing. Carving (Ch.7) will find headers but the recovered files will be checkerboarded with garbage.
Recovery of a RAID 0 with a dead member therefore reduces to a single-disk problem: you must physically recover the dead disk — mechanical work in a clean room (Chapter 8) or flash recovery (Chapter 9) — and only then virtually reassemble the stripe. If the dead member is truly unrecoverable, your only wins are files smaller than one strip that happen to sit entirely on a surviving disk, and the leading strip of larger files. That is usually a thin consolation. RAID 0 exists for speed and scratch space; it should never hold anything that is not backed up, and now you know why.
RAID 1 — mirroring, and the divergence trap
RAID 1 writes the same data to every member. A two-disk mirror is two identical copies; capacity equals one disk.
RAID 1 (mirror) capacity = one disk
+-----------+-----------+
| Disk 0 | Disk 1 |
| A1 | A1 | Every block is written to BOTH.
| A2 | A2 | Read from either; survives N-1 losses.
| A3 | A3 |
+-----------+-----------+
The good news: a single mirror member is a complete, standalone copy of the volume. Image either disk and you can treat it exactly like a single drive from Chapters 6–7. For forensics this is a gift — but a sharp-edged one. The bad news comes in two flavors. First, "both mirrors fail" does happen — same model, same batch, same power event, correlated failure — and then you have two independent single-disk recoveries (Ch.8/9), and you keep whichever member yields more.
Second, and more subtly: the two members may have diverged. If the array ran degraded (one member dropped, writes continued to the other) and was later "repaired" incorrectly — or if a controller wrote to one member but not the other during a crash — the two copies are no longer identical. The disk with the latest writes is authoritative; the stale one holds an older, internally consistent but outdated, file system. Always image both members and compare. The freshest one is identified by file-system journal sequence numbers, the newest MACB timestamps (Ch.21), or controller metadata event counters. Picking the stale mirror because it happened to be in bay 0 is a classic, silent error.
Recovery vs. Forensics. On a RAID 1, a single member is both a fast restore source and a forensic image of the volume — same artifact, two purposes. The recovery tech grabs the freshest mirror and copies files; the examiner images every member, hashes each (Ch.5), documents which physical disk sat in which bay, and notes any divergence between mirrors in the report, because a difference between the two copies can itself be evidence — a sign of degraded operation, tampering, or a specific write that landed on only one disk.
RAID 5 — distributed parity and the XOR that saves you
RAID 5 is the level you will recover most often, and the one where the six unknowns truly bite. It stripes data like RAID 0 but adds one strip of parity per stripe, rotated across all members so no single disk is a parity bottleneck. Minimum three disks; capacity is (N−1) disks. It survives exactly one disk failure.
The parity is the bitwise XOR of the data strips in that stripe:
P = D0 XOR D1 XOR D2 XOR ... XOR D(n-2)
XOR's magic is that it is its own inverse. If any one strip in the stripe is missing — data or parity — you reconstruct it by XOR-ing all the others. Lose data strip D1? Then D1 = P XOR D0 XOR D2 XOR .... That single equation is the entire redundancy of RAID 5.
RAID 5 (4 disks, left-symmetric) capacity = (N-1) disks; survives 1 failure
+--------+--------+--------+--------+
stripe0 | D0=0 | D1=1 | D2=2 | P0 | P0 = 0 XOR 1 XOR 2
stripe1 | D0=4 | D1=5 | P1 | D3=3 | P1 = 3 XOR 4 XOR 5
stripe2 | D0=8 | P2 | D2=6 | D3=7 | P2 = 6 XOR 7 XOR 8
stripe3 | P3 | D1=9 | D2=10 | D3=11 | P3 = 9 XOR 10 XOR 11
+--------+--------+--------+--------+
parity rotates one disk left each stripe
If Disk 2 is dead, reconstruct its strip in every stripe:
stripe0: data block 2 = P0 XOR 0 XOR 1
stripe1: PARITY P1 = 3 XOR 4 XOR 5 (just recompute it)
stripe2: data block 6 = P2 XOR 7 XOR 8
stripe3: data block 10 = P3 XOR 9 XOR 11
So one dead disk in RAID 5 is recoverable by arithmetic, and that is the whole point of the level. The danger — the one this chapter circles back to — is the second failure. Two disks down in a RAID 5 is mathematically unrecoverable from parity: each stripe is now missing two strips, and one XOR equation cannot solve for two unknowns. At that moment your only paths are (a) physically resurrect one of the two failed disks enough to image it (Ch.8/9), reducing the problem back to "one missing," or (b) accept partial recovery of files that, by luck of placement, lost no critical strips. There is no parity trick that conjures two missing strips. Internalize this now, because the most common RAID disaster manufactures exactly this situation.
RAID 6 — dual parity, and why you can't hand-compute Q
RAID 6 adds a second, independent parity (called Q) so the array survives two simultaneous failures. Minimum four disks; capacity is (N−2). P is the same XOR as RAID 5. Q is not an XOR — it is a Reed-Solomon syndrome computed over the Galois field GF(2⁸):
RAID 6 (6 disks) survives 2 failures; capacity = (N-2)
+-----+-----+-----+-----+-----+-----+
stripe0 | D0 | D1 | D2 | D3 | P | Q |
stripe1 | D0 | D1 | D2 | P | Q | D3 | P and Q both rotate
stripe2 | D0 | D1 | P | Q | D3 | D4 |
+-----+-----+-----+-----+-----+-----+
P = D0 XOR D1 XOR ... XOR D(n-3) (plain XOR — easy)
Q = (g^0 . D0) XOR (g^1 . D1) XOR ... (GF(2^8) multiply — hard)
where g = 0x02 and the field uses reduction polynomial 0x11D
The practical takeaway: single-failure RAID 6 recovery is identical to RAID 5 — use P, XOR the survivors. Dual-failure recovery requires solving two simultaneous equations (one in P, one in Q) over the finite field, which you cannot do with a calculator and which is why you reach for a tool that implements the Anvin RAID-6 mathematics correctly. Three disks down in RAID 6 is total loss — back to physical recovery of one of the three. RAID 6 is increasingly common precisely because it tolerates a second failure during a rebuild — the exact scenario that kills RAID 5.
RAID 10 — a stripe of mirrors (and the mdadm wrinkle)
RAID 10 (strictly, RAID 1+0) mirrors first, then stripes: pair the disks into mirrors, then stripe RAID 0 across the pairs. Minimum four disks; capacity is half.
RAID 10 = RAID 0 ( RAID 1 , RAID 1 ) 4 disks, capacity = N/2
Mirror pair A Mirror pair B
+--------+--------+ +--------+--------+
| Disk 0 | Disk 1 | | Disk 2 | Disk 3 |
| A1 | A1 | | A2 | A2 | A1 striped to pair A,
| A3 | A3 | | A4 | A4 | A2 to pair B; each pair
| A5 | A5 | | A6 | A6 | mirrors its own strips.
+--------+--------+ +--------+--------+
Survives ONE failure per pair (best case N/2; guaranteed 1).
Two failures in the SAME pair = total loss.
Recovery is a two-step reduction: identify the mirror pairs (each pair is a copy, so a pair survives as long as one member lives), pick one healthy member from each pair, and you have collapsed the problem into a plain RAID 0 — now solve order and strip size. Do not confuse RAID 10 with RAID 01 (0+1, stripe first, then mirror), which is less resilient and rarer; a single disk loss in RAID 01 degrades an entire stripe set, and a second loss in the other set kills the array.
One genuine trap: Linux mdadm raid10 is not always classic nested 1+0. It supports layouts — near (n2, the default, copies on adjacent disks), far (f2, the second copy stored in the second half of each disk for faster reads), and offset (o2). The far layout in particular scatters the mirror copies in a way that no "find the pairs" intuition will untangle by eye — you must read the layout from the superblock (below) or test it explicitly in a tool. Reconstructing an mdadm far array as if it were classic RAID 10 produces confident, total garbage.
Nested and modern variants — a brief orientation
You will also meet RAID 50 (striped RAID 5 groups) and RAID 60 (striped RAID 6 groups), which recover as "solve each parity group, then solve the top-level stripe." Two failures in the same RAID-50 sub-array are fatal; one per sub-array is survivable. Beyond classic RAID lie three systems that look like RAID but are not, and that defeat classic reconstructors:
- Windows Storage Spaces uses a storage pool carved into 256 MB slabs distributed across columns, with resiliency types Simple/Mirror/Parity. Geometry lives in an on-disk database, not a fixed stripe formula. Reconstruct it with a Storage-Spaces-aware tool (ReclaiMe and UFS Explorer both handle it), not a RAID-5 calculator.
- ZFS (raidz1/2/3) and Btrfs use variable-width, copy-on-write stripes with per-block checksums. There is no fixed strip geometry to discover — the stripe width is tied to each record. Classic RAID reconstructors cannot virtually rebuild raidz; your realistic path is to import the pool read-only on a real ZFS system, or use a specialized ZFS recovery tool. State this limitation plainly to clients before you quote them.
Limitation. The clean six-parameter model in this chapter assumes fixed-geometry striping (RAID 0/1/5/6/10/50/60 as classic controllers and
mdadmimplement them). Copy-on-write checksummed filesystems-as-RAID (ZFS, Btrfs) and database-driven pools (Storage Spaces) break the model. Recognizing which kind of array you are holding — before you promise a result — is itself a core skill (Theme 5).
Parity rotation: left, right, synchronous, asynchronous
Here is where reconstructions silently fail. For RAID 5/6 you must know which disk holds parity in stripe 0 and which way parity rotates as you descend the stripes — and you must know how data blocks are numbered relative to the parity position. There are four canonical RAID 5 layouts. The Linux kernel calls them symmetric/asymmetric; recovery tools (R-Studio, UFS Explorer) call the same things synchronous/asynchronous. They are the same four things under two naming schemes, and the mismatch is a perennial source of error:
NAMING MAP: synchronous == symmetric asynchronous == asymmetric
(a) LEFT-ASYMMETRIC (b) LEFT-SYMMETRIC *most common; mdadm default*
D0 D1 D2 D3 D0 D1 D2 D3
0 1 2 P 0 1 2 P
3 4 P 5 4 5 P 3
6 P 7 8 8 P 6 7
P 9 10 11 P 9 10 11
parity moves right->left, parity moves right->left, data RESTARTS
data fills slots in column just AFTER the parity disk and WRAPS
order (numbering ignores P) (numbering follows the parity rotation)
(c) RIGHT-ASYMMETRIC (d) RIGHT-SYMMETRIC
D0 D1 D2 D3 D0 D1 D2 D3
P 0 1 2 P 0 1 2
3 P 4 5 5 P 3 4
6 7 P 8 7 8 P 6
9 10 11 P 9 10 11 P
parity moves left->right, parity moves left->right, data starts
data fills in column order after parity disk and wraps
Three things distinguish the four:
- Direction — does parity start on the last disk and march left (left layouts), or start on the first disk and march right (right layouts)?
- Symmetry — asymmetric lays data blocks left-to-right across the non-parity slots, numbering independent of the parity position. Symmetric starts the next data block on the disk immediately after the parity strip and wraps around — this keeps sequential reads moving forward across disks, which is why left-symmetric is the highest-performing and the
mdadmdefault, and therefore the one you'll encounter most. - Where stripe 0's parity sits — the starting corner.
Why obsess over this? Because if you pick the wrong layout, the parity strips land where the tool expects data, and you get a volume full of high-entropy noise interleaved with real bytes. The file system may even partially mount and then throw checksum errors deep in directories — the cruelest outcome, because it looks like almost working. There are also two wrinkles: some controllers (notably older Adaptec) use a parity delay, rotating parity only every k stripes instead of every stripe; and RAID 6 multiplies the four into more variants (P-then-Q ordering, left-symmetric-6, etc.). Good tools test all of these for you — but you must understand what they are testing, and you must verify the winner, not just accept the first layout that produces a recognizable boot sector.
Tool Tip. Don't memorize the tables — memorize the method. Reconstruct, then mount read-only and run a file-system consistency check (
chkdsk /fon a copy,fsck -n, or the tool's own integrity scan) and open several large files of different types from deep in the directory tree. A correct layout opens a 50 MB CAD file and a deeply nested PDF cleanly. A wrong-but-close layout opens the boot sector and the root directory and then corrupts. Verification beats cleverness.
Virtual RAID reconstruction: rebuilding the array without the controller
"Virtual" reconstruction means assembling the logical volume in software, from images of the bare member disks, without the original controller. This is the core skill of the chapter and the daily work of a recovery shop, because controllers die, vendors discontinue models, firmware versions become incompatible, and — for forensics — you are often handed only the drives, pulled from a server you'll never see. You discover the six parameters and feed them to a tool, which presents the combined volume as if the controller still lived.
Step 0 — Image every member first (non-negotiable)
Before any analysis, make a sector-by-sector image of every member, including the ones marked "failed" (they are usually mostly readable, and in RAID 5 a single bad member is still useful — parity covers its gaps). Use a write-blocker (Ch.14) and a tool that tolerates bad sectors, logging exactly which sectors could not be read:
# Image each member to its own file, with a map of unreadable regions.
# -d direct I/O (bypass cache), -r3 three retry passes on bad sectors.
sudo ddrescue -d -r3 /dev/sdb member1.img member1.map
sudo ddrescue -d -r3 /dev/sdc member2.img member2.map
sudo ddrescue -d -r3 /dev/sdd member3.img member3.map
sudo ddrescue -d -r3 /dev/sde member4.img member4.map # the "failed" one
# Hash every image immediately for chain of custody / verification.
sha256sum member*.img > members.sha256
Why this is the first rule and not the fifth: every reconstruction technique below is a hypothesis test. You will try an order, a strip size, a layout; you will be wrong several times; each wrong attempt with a tool that writes (or a controller that "repairs") risks the originals. Working on images means a wrong guess costs nothing but time. The original is sacred (Theme 2) — and on a RAID, "the original" is all the members at once.
Step 1 — Determine the member set (and detect the stale one)
Confirm which disks belong to the array and whether one is stale — a disk that dropped out earlier while the array kept running, so its data is an older, internally consistent snapshot. Including a stale member is as bad as including a wrong disk: the file system mounts and quietly serves old file contents from that disk's strips. Stale members are betrayed by event/sequence counters in the controller metadata (a lower Events value than its peers) or, absent metadata, by inconsistent parity (a stripe whose XOR doesn't check out points at the out-of-date strip). The rule for RAID 5 with one dead and one stale member: rebuild from the freshest N−1 disks and let parity fill the dead one's gaps — do not drag the stale disk back in.
Why This Matters. "Every action leaves a trace, and the absence of a trace is itself a trace" (Theme 3). A stale member's low event counter is a trace of when it dropped; a parity mismatch on a particular disk is a trace of staleness even when metadata is gone. The same forensic instinct that catches timestomping (Ch.21) catches the wrong disk in a RAID.
Step 2 — Read on-disk metadata (the best case)
Many arrays write down their geometry. If you can read it, the six unknowns collapse to a five-minute job. The big three:
- Linux
mdadmwrites a superblock with magic0xA92B4EFC. Version 1.2 sits at byte offset 4096 from the start of the member; v1.1 at offset 0; v1.0 and the legacy v0.90 at the end of the device. It records level, chunk size, layout, data offset, the array UUID, each disk's role (= order!), and an event counter. - Hardware controllers often use SNIA DDF (Disk Data Format), anchor signature
0xDE11DE11, typically in a reserved area at the end of the disk. - Intel Rapid Storage / IMSM writes the literal signature
Intel Raid ISM Cfg Sig.near the end of the disk.
Reading an mdadm superblock turns guesswork into transcription:
$ sudo mdadm --examine /dev/sdb1
/dev/sdb1:
Magic : a92b4efc
Version : 1.2
Array UUID : 7c2f1a9e:3b4d5e6f:8a9b0c1d:2e3f4a5b
Name : nas01:0
Creation Time : Tue Mar 4 21:14:07 2024
Raid Level : raid5
Raid Devices : 4
Avail Dev Size : 7813771264 sectors (3.64 TiB)
Array Size : 11720656896 KiB (10.92 TiB)
Data Offset : 264192 sectors <-- parameter 5 (start offset)
Super Offset : 8 sectors
State : clean
Update Time : Sat Jun 21 02:47:33 2025
Checksum : a1b2c3d4 - correct
Events : 41273 <-- compare across members!
Layout : left-symmetric <-- parameter 4 (parity layout)
Chunk Size : 512K <-- parameter 3 (strip size)
Device Role : Active device 1 <-- parameter 2 (this disk's order)
Array State : AAAA ('A'==active '.'==missing 'R'==replacing)
Run --examine on every member, line up the Device Role values to get the order, confirm all Events counters match (a laggard is your stale disk), and read off chunk size, layout, and data offset. That single block answers five of the six unknowns. Always try metadata first — empirical reconstruction (next) is what you do when the metadata is proprietary, overwritten, or gone.
Step 3 — Determine strip size empirically
When metadata fails you, the disks themselves still carry tells. Strip size reveals itself at the boundaries where the controller switched disks. Find a long, predictable run of bytes — a big contiguous file (a video, a disk image, a database), a region of zeroes, or a repeating pattern — and watch for the point where the pattern abruptly jumps to a different disk's content. That jump is a strip boundary; the distance between jumps is the strip size. Because strip sizes are always powers of two (16K, 32K, 64K, 128K, 256K, 512K), tools test each candidate and score how cleanly file-system structures align. The right strip size makes NTFS MFT records (1024-byte aligned, signature FILE = 46 49 4C 45) and ext4 superblock copies (magic 0xEF53 at known block-group offsets) fall exactly where the file system expects them; the wrong size scatters them.
Step 4 — Determine disk order
Disk order is not bay order — controllers number internally, drives get re-seated, and bays get swapped during panic. Order is recovered by finding structures that span a stripe and seeing which sequence makes them continuous. The richest anchors live at the very front of the volume, which sit on the disk holding stripe 0, block 0:
Offset 0 of the reconstructed volume should look like a boot sector:
00000000 EB 52 90 4E 54 46 53 20 20 20 20 00 02 08 00 00 |..NTFS .....|
^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ "NTFS " OEM ID at offset 3
000001F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 AA |..............U.|
^^ ^^ 0x55AA at 0x1FE
If a candidate order puts that boot sector at offset 0 and the $MFT exactly where the boot sector's BPB says it should be (the MFT cluster field at byte 0x30), and directory entries on the next disk continue coherently, the order is probably right. Tools brute-force the orderings (only N! of them, and N is small — 24 orderings for four disks) and score each against file-system coherence. For a forensic reconstruction you will document the winning order against the physical disks (serial numbers, bay positions) so the result is reproducible.
Step 5 — Determine parity rotation and start offset
With members, order, and strip size in hand, parity is found by testing the four (or more) layouts and checking which makes parity strips actually be parity: in a correct layout, the strip the layout designates as parity equals the XOR of the other strips in that stripe. Tools verify this across thousands of stripes and pick the layout with the most consistent parity. The start offset (data offset) is the size of the metadata region before array data begins — read from the superblock when present, or found by sliding the assumed start until the boot sector and file-system structures snap into alignment. Many software arrays use a 1 MiB (2048-sector) offset; modern mdadm reserves much more (the example above shows 264192 sectors ≈ 129 MiB to leave room for reshape). Get the offset wrong and everything is shifted — the array looks like noise from byte zero.
Step 6 — Assemble the virtual array and verify
Now you have all six. The tool combines the images into one logical volume. The reconstruction math, for the common left-symmetric RAID 5, is short enough to read — this maps a logical byte offset to a physical (disk, offset) pair, which is exactly what a virtual-RAID layer does on every read:
def map_raid5_left_symmetric(logical_off, n_disks, strip, data_offset=0):
"""Return (disk_index, physical_offset) for a logical byte offset.
n_disks includes the parity disk; data disks per stripe = n_disks - 1.
Illustrative: assumes a healthy array (no reconstruction needed)."""
data_disks = n_disks - 1
lbn = logical_off // strip # logical strip number
in_strip = logical_off % strip # offset within the strip
stripe = lbn // data_disks # which stripe row
data_index = lbn % data_disks # which data slot in the row
# left-symmetric: parity starts on the LAST disk and marches left
parity_disk = (n_disks - 1) - (stripe % n_disks)
# data fills the slot just AFTER parity, wrapping around
disk = (parity_disk + 1 + data_index) % n_disks
phys = data_offset + stripe * strip + in_strip
return disk, phys
def reconstruct_missing_strip(strips_present):
"""RAID 5 / single-parity: XOR all present strips to recover the one
that is missing (works whether the missing strip was data OR parity)."""
out = bytearray(len(strips_present[0]))
for s in strips_present:
for i, b in enumerate(s):
out[i] ^= b
return bytes(out)
The final, mandatory step is verification, not celebration. Mount the reconstructed volume read-only, run a file-system check that does not write, and open real files from deep in the tree — several types, several sizes. A reconstruction that produces a mountable file system but corrupts files in subdirectories has a wrong strip size, order, or layout that only shows up past the first stripe rotation. Only when large files open cleanly and the file-system check is clean do you trust the geometry — and only then do you image the reconstructed volume or copy data off it.
Recovery technique: from raw members to recovered files 💾
For pure data recovery, the goal is the files, fast, and the workflow is linear: image every member → reconstruct virtually → mount read-only → copy out, prioritizing what matters. You do not "fix" the array; you build a faithful virtual copy and harvest from it. If the file system on the reconstructed volume is itself damaged (a crash during the failure corrupted the MFT or inode tables), fall back to the logical-recovery techniques of Chapter 6 and, where metadata is gone, file carving from Chapter 7 applied to the reconstructed volume — carving across a correctly assembled array recovers whole files, whereas carving a single member recovers only strip-sized fragments. Triage by value: in the architecture-firm scenario, the three active-construction projects come off first, then the eight-year archive. Restoration order is a human decision (Theme 6) as much as a technical one, and it is the recovery business's stock-in-trade (Chapter 13).
War Story. A managed-service provider brought us a six-bay RAID 5 NAS that "wouldn't come back after a power blip." Two drives showed amber. The MSP had already tried the controller's Rebuild twice. We imaged all six members anyway — including the two "failed" ones. Five imaged perfectly; the sixth had 312 unreadable sectors clustered in one region. Because RAID 5 covers one missing strip per stripe with parity, we reconstructed virtually using the five clean images plus parity to fill the sixth disk's 312 bad spots — and lost data only in the handful of stripes where a second member also happened to have a bad sector at the same offset. Final result: 99.998% of files recovered. Had we let the controller finish its rebuild onto a replacement, it would have written reconstructed-from-incomplete-data parity over good strips and turned a near-total recovery into a partial one. Image first. Always.
Forensic technique: the array as evidence 🔍
When the array is evidence — a seized server, a litigation hold, the file server in the corporate IP-theft investigation of our running anchor case — the discipline tightens at both ends. Before you pull a single drive, document the physical configuration: photograph the server, the bay layout, and cabling; record each drive's make, model, serial number, and the bay it occupied; note the controller model and firmware. Bay position can matter to order, and even when it doesn't, chain of custody requires that you can say which physical object yielded which image. Then image each member behind a write-blocker, hash each image (Ch.5, Ch.14), and only then reconstruct — virtually, from the verified images, never from the originals.
The forensic deliverable is not just "the recovered volume" but a reproducible reconstruction: record the order, strip size, parity layout, and data offset you derived, and how you derived them, so a second examiner can independently rebuild the identical volume from the same images. That reproducibility is what survives a Daubert challenge (Chapter 25) and what you defend on the stand (Chapter 27). Your report (Chapter 26) states the parameters explicitly and notes any member that was stale, reconstructed from parity, or partially unreadable, because each of those affects how much weight the evidence can bear.
Recovery vs. Forensics. Same array, same six parameters, two postures. The recovery tech reconstructs to get files back and is done when the client's data opens. The examiner reconstructs to get admissible files back and is done only when the reconstruction is hashed, documented, reproducible, and the parameters and any imperfections are written into a report. The technical act of XOR-ing parity is identical; the surrounding rigor is the whole difference between "I got the data" and "I can prove this is the data and it is unaltered."
Chain of Custody. Label each drive physically with its bay position and a unique exhibit ID before it leaves the chassis (E1-bay0, E2-bay1, ...). Drives in a pile of identical disks become anonymous in minutes, and "which disk was in which bay" is sometimes the difference between a clean order and a guess. Record serials on the custody form; photograph the labels.
Ethics Note. A server array often holds an entire organization's data — every employee's files, not just the subject's. Your authority (warrant scope, consent, engagement letter) may cover one custodian or one matter, not everyone. Reconstruct the whole volume if you must to access anything, but scope your examination to what you are authorized to review, document what you excluded, and protect everything else. The capacity to read all of it is not authorization to read all of it (Ch.28).
Tool demonstration
No one hand-XORs a 10 TB array. Four tools cover essentially all classic-RAID recovery; see Appendix C for the full reference.
ReclaiMe Free RAID Recovery — parameter detection
ReclaiMe Free RAID Recovery is exactly what its name says: free, and laser-focused on solving the six unknowns. You point it at the member images; it analyzes them and reports order, strip size, parity rotation, and start offset. It is the ideal teaching tool because it isolates parameter discovery from everything else, and it exports the recovered configuration so you can feed it to a recovery tool that does the file extraction:
ReclaiMe Free RAID Recovery — Analysis complete
Array type ............ RAID 5
Number of disks ....... 4 (1 missing — reconstructed from parity)
Disk order ............ #2, #4, #1, #3 (by serial)
Block (strip) size .... 65536 bytes (64 KB)
Parity .............. .. left-symmetric (rotation: backward)
Start offset .......... 1048576 bytes (sector 2048)
Confidence ............ 99.4%
-> Export to: ReclaiMe / R-Studio (.rcfg) / virtual image (.vim)
R-Studio — manual and automatic reconstruction
R-Studio (R-TT) is a full commercial recovery suite with strong RAID support. You can let it detect parameters or build the array manually in the RAID editor — drag member images into slots, set type, strip size, and the parity layout from a dropdown (where you'll see the synchronous/asynchronous naming from earlier). Build, then scan the virtual volume exactly as you would a single disk; R-Studio then recovers files with their original names and folder structure when file-system metadata survives, or by signature when it doesn't.
UFS Explorer RAID Recovery — flexible builder
UFS Explorer RAID Recovery (SysDev Laboratories) provides a visual RAID builder supporting an unusually wide range of layouts, parity-delay schemes, nested arrays (RAID-on-RAID, e.g., RAID 50/60), and the non-classic systems noted earlier (Storage Spaces, some ZFS scenarios). It can import controller metadata when present and assemble automatically, or accept parameters you supply manually. Its strength is handling the odd configurations that trip up simpler tools.
Linux mdadm and losetup — software RAID, and the --create landmine
For Linux software RAID, the safest reassembly reads the geometry from the superblocks and does not guess. Attach the images as loop devices and assemble read-only:
# Attach each member image as a loop device.
sudo losetup -f --show member1.img # -> /dev/loop0
sudo losetup -f --show member2.img # -> /dev/loop1
sudo losetup -f --show member3.img # -> /dev/loop2
sudo losetup -f --show member4.img # -> /dev/loop3
# Assemble READ-ONLY from the superblocks (reads order/chunk/layout/offset).
sudo mdadm --assemble --readonly /dev/md0 \
/dev/loop0 /dev/loop1 /dev/loop2 /dev/loop3
sudo mount -o ro,norecovery /dev/md0 /mnt/array
--assemble is safe because it reads the recorded parameters — including the all-important data offset. The dangerous sibling is --create, which you should avoid unless you know every parameter exactly and run it only on copies, with --assume-clean so it does not recompute (and overwrite) parity:
# DANGER. Copies only. --assume-clean prevents a parity rebuild that would
# overwrite data; 'missing' leaves a dead/stale slot empty so md fills it
# from parity instead of trusting an out-of-date disk.
sudo mdadm --create /dev/md0 --assume-clean \
--level=5 --raid-devices=4 --chunk=512 --layout=left-symmetric \
--data-offset=264192s \
/dev/loop0 /dev/loop1 missing /dev/loop3
The lurking trap: modern mdadm --create chooses its own default data offset, which is frequently different from the offset the array was originally created with. Re-create with the wrong offset and the new array is shifted relative to the real data — you'll see noise where the boot sector should be. That is exactly why --assemble (which honors the recorded offset) is preferred, and why, if you must --create, you pass --data-offset= to match the original precisely.
Limitation.
mdadm --createis write-capable. Pointed at original drives instead of copies, a single wrong invocation writes new superblocks and (without--assume-clean) starts a parity rebuild — destroying the very data you came to save. This is a software version of the forced-rebuild disaster below. The defense is unchanged: work on images.
Worked example: a four-disk RAID 5 after a controller death
Return to the architecture firm. The NAS motherboard (the "controller") is dead; the four 4 TB drives are physically fine. Here is the full reconstruction.
1 — Acquire. Pull all four drives, label each with its bay (bay0–bay3) and serial, photograph the chassis, and image every drive behind a write-blocker with ddrescue, hashing each image. All four image cleanly (the failure was the controller, not the disks).
2 — Identify type and read metadata. mdadm --examine on each image returns the superblock shown earlier: raid5, four devices, left-symmetric, Chunk Size 512K, Data Offset 264192 sectors, all four Events counters equal at 41273 (so no stale member). Five of six unknowns answered from metadata; the order comes from the Device Role line on each member.
member1.img Device Role: Active device 0 Events: 41273
member2.img Device Role: Active device 1 Events: 41273
member3.img Device Role: Active device 2 Events: 41273
member4.img Device Role: Active device 3 Events: 41273
Array State : AAAA (all members active, none missing)
3 — Assemble virtually, read-only.
for f in member1 member2 member3 member4; do sudo losetup -f --show $f.img; done
sudo mdadm --assemble --readonly /dev/md0 /dev/loop{0,1,2,3}
sudo mount -o ro,norecovery /dev/md0 /mnt/array
4 — Verify. The reconstructed volume mounts as a 10.92 TiB NTFS file system. The boot sector is at offset 0 with the 55 AA signature; the $MFT is where the BPB points; a read-only ntfsfix-style consistency check is clean. You open a 240 MB Revit model from a 2024 project folder and a deeply nested PDF — both open perfectly. The geometry is correct.
5 — Recover, by priority. Copy the three active-construction project folders first to fresh media, verify a sample with hashes, then the full archive. Where any directory shows MFT damage, fall back to Chapter 6 MFT-record recovery; where metadata is gone, carve from the reconstructed volume per Chapter 7. Total time: a few hours of imaging, minutes of reconstruction, and a long copy. The firm's buildings are back.
Had the metadata been proprietary or wiped, steps 2–3 would have become the empirical hunt of the previous section — strip size by boundary analysis, order by boot-sector/MFT coherence, parity by XOR-consistency testing, offset by alignment — most likely driven by ReclaiMe or R-Studio rather than mdadm. The method is identical; only the source of the parameters changes (Theme 4: technology varies, the method is constant).
The most common RAID disaster: the forced rebuild
Now the disaster that fills recovery benches — the one the architecture firm walked straight into, and that nearly every shop sees weekly. It is not exotic hardware failure. It is a forced rebuild of a degraded array that triggers a second failure.
Trace the mechanism on a RAID 5:
THE DEGRADED-REBUILD CASCADE (RAID 5)
Day 0 Disk 2 fails. Array goes DEGRADED: still serving data on the
remaining 3 disks, but now with ZERO redundancy. One more fault
anywhere = data loss. (Most users don't feel any difference here.)
Day 5 A replacement disk is inserted. The controller starts a REBUILD:
it must READ EVERY SECTOR of all 3 surviving disks and XOR them
to recompute Disk 2's contents onto the new drive. Hours of
100%-busy, full-surface reads on aging, same-batch disks.
Hour 4 Disk 1 hits a latent Unrecoverable Read Error (URE) on a sector
it hasn't been asked to read in a year. The controller now has
TWO members unavailable for that stripe -> cannot compute parity
-> aborts the rebuild and marks the ARRAY FAILED / OFFLINE.
Result A single-disk failure (fully recoverable) has become a two-disk
failure (NOT recoverable from parity). The rebuild itself caused
the second failure.
Why is the rebuild the moment of death rather than normal operation? Three compounding reasons:
- Latent sector errors stay hidden until read. A drive can carry unreadable sectors for months in regions no one touches. A rebuild reads every sector of every surviving disk — often the first full-surface read in a year — and that is when latent errors surface, all at once, under load.
- The math is against large arrays. Consumer SATA drives quote an unrecoverable read error rate around 1 in 10¹⁴ bits ≈ 11.4 TiB. Rebuilding a RAID 5 of, say, six 4 TB drives means reading ~20 TB across the survivors — statistically more than one URE expected. The bigger the disks, the worse the odds; this single statistic is why RAID 6 (which survives that second fault) displaced RAID 5 for large arrays.
- Correlated failure. Array disks are typically the same make, model, batch, age, and duty cycle, sitting in the same heat and vibration. The conditions that killed disk 2 are working on the others — and the rebuild's hours of maximum stress are exactly when a marginal sibling tips over.
It gets worse than "the rebuild stops." Some controllers, when an admin re-seats the original failed disk and forces it back online, rebuild backward — pushing stale data over good. Re-initializing or re-creating the array in the controller BIOS can write fresh metadata and zero the parity, which is unrecoverable. Even reordering drives in the bays can make a controller fail to recognize the set and offer to initialize it — and a tired admin clicks "yes." Each of these is a human action that converts a recoverable situation into a partly- or fully-unrecoverable one.
The correct response to a single failed disk in a RAID 5/6 — the procedure that would have saved the firm — is restraint:
- Stop. Do not let an automatic, unsupervised rebuild run on aging disks. A degraded array that is powered off is stable; a degraded array being rebuilt is at maximum risk.
- Image every surviving member first (and the "failed" one too — it is usually mostly readable), behind a write-blocker, with a bad-sector-tolerant imager, hashing each image.
- Reconstruct virtually from the images. If a second disk has bad sectors, you are usually fine: RAID 5 parity fills one missing strip per stripe, so single bad sectors scattered across different disks are covered; only stripes where two members are bad at the same offset are lost. This is the everyday miracle of imaging first — a "double failure" on the controller becomes a near-total recovery on the bench, because the two failures rarely overlap stripe-for-stripe.
- Never
mdadm --createor controller-re-initialize over the originals. If you must re-create, do it on copies, with--assume-cleanand the exact original--data-offset.
War Story. A law firm's accounting server, RAID 5, dropped a disk on a Thursday. IT replaced it Friday at 5 p.m. and left the rebuild running over the weekend. Monday: the array was offline, two disks "failed." Panic, because payroll ran Tuesday. We received five... no, three drives and a replacement. We imaged all of them, including both "failed" originals. The first failed disk was 100% readable (it had merely been kicked from the array by a timeout, not physically dead); the second had 47 bad sectors. We reconstructed using the freshest three originals — excluding the replacement entirely, since the rebuild had written incomplete, now-wrong data to it — and parity covered the 47 bad spots from non-overlapping disks. Full recovery. The lesson the firm learned the hard way and you can learn here: the replacement disk and its rebuild were the enemy; the "failed" originals were the rescue.
Legal Note. In litigation, forcing a rebuild on original evidence drives can constitute spoliation — the destruction or material alteration of evidence — with sanctions ranging from adverse-inference instructions to case-ending penalties (Ch.25). "We were just trying to fix it" is not a defense once a litigation hold is in place. Image first is not only good recovery practice; on evidence it is a legal duty.
Common mistakes
- Treating RAID as a backup. It is redundancy against disk failure, not against deletion, corruption, ransomware, fire, or human error. A ransomware-encrypted array is uniformly encrypted across every member; reconstruction yields a perfectly assembled encrypted volume (see Chapter 12). RAID buys uptime, not a second copy.
- Letting the controller rebuild before imaging. The single most expensive error in this chapter. A rebuild stresses aging disks at the worst moment and can overwrite good data with reconstructed-from-incomplete parity. Image every member first; reconstruct virtually.
- Confusing bay order with disk order. Drives get re-seated and bays get swapped during panic. Derive order from metadata (
Device Role) or from file-system coherence — never assume the bays. - Including a stale member. A disk that dropped earlier holds an older, internally consistent file system; include it and you serve old file contents with no obvious error. Compare event counters; check parity consistency; exclude the laggard.
- Guessing the strip size by a factor of N. "Stripe size" ambiguity (per-disk strip vs. full-stripe width) produces an off-by-N error that fails the whole reconstruction. Confirm which number you have.
- Picking the wrong parity layout and stopping at the boot sector. A near-right layout mounts the file system and corrupts files deep in the tree. Verify by opening large files from subdirectories and running a read-only consistency check — not by seeing offset 0 look plausible.
- Re-initializing the array in the controller BIOS. "Repair," "Initialize," and "Create" in a controller menu can write new metadata and zero parity. When in doubt, power off and image; never click a controller action you can't undo.
- Reconstructing ZFS/Btrfs/Storage Spaces as classic RAID. Variable-width and database-driven layouts have no fixed stripe geometry; a RAID-5 calculator produces confident garbage. Identify the system first.
mdadm --createon originals. Write-capable; without--assume-cleanand the correct--data-offsetit overwrites the data you came for. Use--assemble(read-only) whenever metadata exists.
Limitations: knowing when to stop
RAID reconstruction has hard walls, and a professional names them before quoting a job (Theme 5). Beyond the redundancy budget, the math is final: two unrecoverable members in RAID 5, three in RAID 6, both members of a mirror pair in RAID 10 — none can be conjured from parity, and your only remaining move is the physical recovery of one more member (Ch.8/9). If that fails, the array is, in part, genuinely gone. A forced rebuild that has already overwritten parity or written incomplete data to a replacement may have destroyed the redundancy you needed; if the originals were not imaged before the rebuild, you may be left with only the partial result the controller produced. Encryption sits on top of RAID: reconstruct a BitLocker- or LUKS-protected array perfectly and you still hold ciphertext until you have the key (Chapter 29). Copy-on-write checksummed systems (ZFS raidz, Btrfs) defy fixed-geometry reconstruction entirely. And file-system damage layered on top of array damage — a crash that corrupted the MFT during the failure — means a correct reconstruction still needs Chapter 6 logical recovery and Chapter 7 carving to finish the job. "I reconstructed the array correctly and this much is recoverable; the rest is mathematically or physically lost" is a complete, honest, professional finding.
Progressive project: when your case source is an array
Your Forensic Case File so far has treated evidence as single images. Real servers are arrays, so extend the project. Suppose the case server in the corporate IP-theft matter turns out to be a four-disk RAID 5. Add to your case file: (1) a physical-configuration record — each drive's serial, the bay it occupied, the controller model, with a photograph; (2) a per-member acquisition log — image filename, hash, and ddrescue map for each disk; (3) a reconstruction parameters block — order, strip size, parity layout, and data offset, and how you derived each (metadata vs. empirical), written so a second examiner can reproduce the exact volume; and (4) a verification note — the read-only consistency check result and a sample of files opened to confirm geometry. From there, your existing timeline (Ch.21) and artifact analysis (Ch.16–20) run against the reconstructed volume exactly as they would against a single image. The reconstruction parameters are now part of the evidentiary record — because in court, how you combined the disks is as much a part of your method as how you imaged them (Ch.26–27).
Summary
RAID turns one storage problem into a system problem: data that no single disk contains, scattered as strips and parity across members in a geometry the controller knew and you must rediscover. Every striped array is defined by six parameters — member set, disk order, strip size, parity layout, start offset, and special rules — and virtual reconstruction is the disciplined process of discovering all six and assembling the volume in software, from images of the bare disks, without the original controller. The level dictates the redundancy budget: RAID 0 dies with one disk; RAID 1 mirrors survive until both copies fail (watch for divergence); RAID 5 reconstructs one missing strip per stripe by XOR but dies with two; RAID 6 adds Reed-Solomon Q to survive two; RAID 10 reduces to "find the mirror pairs, then solve a RAID 0." Parity has four canonical rotations (left/right × symmetric-synchronous/asymmetric-asynchronous), and choosing wrong produces convincing corruption. Tools — ReclaiMe Free RAID Recovery, R-Studio, UFS Explorer, and Linux mdadm/losetup — automate the parameter hunt and the assembly, but you verify the result by opening real files, never by trusting the first plausible boot sector. Above all looms the chapter's central lesson and the most common RAID disaster: a forced rebuild on a degraded array stresses aging, same-batch disks until a second URE turns a recoverable single failure into an unrecoverable double failure — or overwrites good data with reconstructed-from-incomplete parity. The defense is the oldest rule in the book: image every member first, reconstruct virtually, work only on copies. The original is sacred — and on a RAID, the original is all the disks at once.
You can now: - Explain how RAID 0, 1, 5, 6, and 10 fail, and how many members each level can lose before data is unrecoverable. - Enumerate the six parameters that define any striped array and explain why each matters to reconstruction. - Reconstruct a RAID virtually from member images — reading metadata when present, or empirically deriving strip size, disk order, parity rotation, and start offset when it is not. - Reconstruct a single missing RAID 5 strip by XOR and explain why two missing strips cannot be recovered from parity. - Drive ReclaiMe, R-Studio, UFS Explorer, and
mdadm/losetup, and avoid the--create/controller-re-initialize landmines. - Recognize and prevent the forced-rebuild cascade, and reconstruct an array reproducibly enough to defend it as evidence.
What's next. Chapter 11 — Mobile Device Recovery — leaves spinning platters and parity behind for the locked, encrypted, soldered-flash world of phones and tablets, where the recovery target is a single device that fights you at every layer.
Practice in exercises.md, test yourself with the quiz, apply it in the case studies, review the key takeaways, and go deeper with further reading.