Unreadable MFT clusters on NVMe showed 100% spare blocks
chkdsk reported 4 consecutive unreadable MFT file-record segments (0x71FD88–0x71FD8B) on my ADATA LEGEND 710 NVMe. Reading that cluster during the scan emitted 133 fresh disk Event-7 bad-block events at 15:49:49. The volume was not dirty.
Windows does not expose full NVMe SMART log page 0x02 on this device even elevated. Available Spare and Media-and-Data-Integrity-Errors were unobtainable through Get-StorageReliabilityCounter, MSFT_PhysicalDisk, or fsutil.
What CrystalDiskInfo showed
CrystalDiskInfo 9.9.1 read the NVMe SMART log pages that Windows would not expose.
- Available Spare: 0x64 = 100% (threshold 0x20 = 32%). Zero reserve blocks consumed.
- Media and Data Integrity Errors: 0x17 = 23 lifetime
- Percentage Used: 0x03 = 3%
- Health Status: Good, 97%
- Power On Hours: 2,228
- Total Host Writes: 17,551 GB
- Unsafe Shutdowns: 0x21 = 33
100% available spare with only 23 lifetime media errors ruled out progressive failure. The four bad MFT segments and four known user files with CRC errors are fixed historical damage on a healthy, unworn drive.
The rescue copies
I copied 105,310 files (12.37 GB) of irreplaceable data to G:\My Drive\DiskRescue-2026-07-23. Zero genuine media read failures. A second pass copied 1,700 files (228 MB) of loose project root files and config extras (.claude.json, .claude\memory, .memstack). Zero media read failures.
G:\ root was not writable (Google Drive virtual mount). I placed the rescue folder under G:\My Drive\ with user approval.
Get-ChildItem -Recurse then filter was catastrophically slow on node_modules and models trees. I pruned excluded directories during traversal instead of after.
Google Drive sync latency caused 508 false "missing" results in the first verify run. All resolved on recheck after a 60-second pause.
I skipped 3 raw-credential files (oauth_token, license.json, license-cache.json). I copied .claude.json with a credentials flag because it was explicitly requested.
I ran all PowerShell via script files, never inline -Command. Shell passthrough kept mangling $ variables this session.