Scanning voids sounds simple until your data comes back corrupted

I spent about three years building custom scan pipelines for a data migration tool, and the most expensive failures never came from the scanners themselves. They came from the assumptions people made about what "empty" actually meant.

The core problem is that void spaces in storage systems are not uniform. A void in an SSD behaves differently than a void in a spinning disk. A void in a network mount looks different than one on local NTFS. When you run a scan across heterogeneous storage, the results are often worse than running nothing at all, because partial information is more dangerous than missing information. What most people miss is that void scans have a specific failure mode where the scanner writes metadata but not the actual payload data, creating a phantom record. The file shows up in reports. The path is valid. But there is nothing at the end of it. This is not a rare edge case. I found this exact pattern in production at a mid-size logistics company where their void scan reports showed 12 terabytes of clean voids that did not exist. The storage array was actually 87 percent full. They nearly shut down a warehouse system because the scans told them there was space that was not there. The workaround I ended up using was surprisingly simple. Run a secondary verification pass using direct block-level reads rather than trusting the filesystem metadata. Read the actual sectors. Count the zeros yourself. If the blocks are not zeroed out, they are not void, even if the FS driver says they are. This added about eight minutes to a typical four-hour scan job, but it caught the phantom voids reliably. The tool I settled on was a modified version of dd combined with a checksum comparison loop. Here is the rough structure:

First, identify the candidate void ranges from your initial scan. Export them to a CSV with start sector, end sector, and size. Then run a block read pass over each range and compute a SHA-256 of the returned bytes. Zero-padded ranges hash to a known constant. Anything else is real data hiding behind a void flag. You can script this in Python in under 150 lines. I wrote one that ran across Windows and Linux partitions interchangeably, though you need to handle volume mounting permissions carefully on Windows or the block read fails silently and gives you false zeros. Another thing beginners overlook is that void scan configuration matters more than the scan engine itself. If your scanner is set to skip mounted volumes or exclude system partitions, you will get incomplete results that look clean. I have seen people celebrate a zero-void report and then wonder why their storage was full three weeks later. The empty space was somewhere the scan never looked. Make sure your scan covers every volume you care about, including hidden recovery partitions if those are part of your storage equation. The scan parameters should be explicit about scope, not implicit. There is also a timing issue with void scans on rotating disks. If you are scanning a busy production drive, the read heads bounce around enough that void detection accuracy drops. The scanner may report a range as partially void when it is actually mixed. This is why I always schedule void scans during low-IO windows and avoid running heavy writes simultaneously. It does not eliminate the problem entirely, but it reduces false positives by roughly half in my experience. If you cannot control the schedule, consider using a read-only snapshot first, then scan the snapshot instead of the live volume. This trades scan time for accuracy, which is usually the right trade.

The hardest part of void scanning is not running the tool. It is interpreting the output correctly. Most scanners give you percentages and totals. They do not tell you which files are involved or whether the void ranges overlap with active data. I learned this the hard way when a void scan reported a large clean range and someone deleted files from it, assuming the space was free. Those files were still linked in the MFT or inode table. Deletion removed the pointers but not the data blocks. The void scan would not flag that. Only a forensic-level examination of the raw structures would catch it. If you need a practical starting point, the simplest reliable setup is a live Linux USB with a standard dd command piped to a hash calculator, run against the target partition while it is unmounted. For Windows, PowerShell can invoke the Win32_DiskDrive WMI class to enumerate raw devices, then you use a Cor Python script with kernel-level read access to do the same thing. This is slower than commercial tools but it does not trust any vendor's internal definitions of what counts as a void. I also want to flag one specific scenario where void scans fail completely. On ZFS or Btrfs with copy-on-write enabled, empty space is managed at the pool level and virtualized through the filesystem. A standard void scanner will see apparent voids that are actually just unwritten CoW blocks. The storage overhead is different. If you are on a modern filesystem with deduplication or compression, void scan results need to be filtered through a filesystem-aware lens, or you will misread the actual available capacity by a significant margin. I usually pair the void scan with a separate pool-level usage report to cross-check. It takes longer but it prevents the kind of planning errors that cost real money.

Get the Full Details

Urgent Warning: The Untold Story Behind Void Scans You Can’t Ignore ...
Urgent Warning: The Untold Story Behind Void Scans You Can’t Ignore ...