Tunas Akara
Back to Blog

Recovering Fragmented Video When File Carving Gives Up

by RayhanUpdated 8 min read
data-recoveryvideoforensicsfilesystems
Recovering Fragmented Video When File Carving Gives Up

Recovering Fragmented Video When File Carving Gives Up

Fragmented video that fails carving isn't gone. It needs cluster-level reassembly: classify the content, score the joins, assemble candidates, verify globally. The method is slow and expensive, but it works on the cases that break every standard tool.

The case that defines it: a flash drive holding irreplaceable, one-off event footage. The filesystem was too damaged to mount. Every standard recovery tool returned files that refused to play.

That's not hopeless — it's just past the point where off-the-shelf tools stop. Reaching the footage means treating recovery as a reconstruction problem, not an extraction problem.

Step one is always an image

Nothing touches the original media except one tool, once: ddrescue. It produces a full image and a map file recording exactly which sectors read cleanly. The discipline behind that rule is covered in image the disk first with ddrescue — here, the point is what the map tells you.

In this case the map was the first diagnosis: a clean read, every sector recovered on the first pass. That single fact reframes the whole job. The drive isn't dying, there's no hardware clock ticking — the problem is purely logical, filesystem corruption plus fragmentation.

From that moment the physical drive goes on a shelf. Every subsequent step runs against the image, where a wrong move costs nothing and can be repeated forever.

Why carving fails on fragmented video

Signature carving — the PhotoRec-class approach — scans for file headers and copies clusters forward from each one until it hits a size limit or the next header. Its unstated assumption: files are contiguous. A carved MP4 is only a valid MP4 if its clusters sat next to each other on disk.

Video breaks that assumption more than any other file type. Video files are the largest objects on any consumer drive. A drive that's lived a few years of writes and deletes has fragmented free space, so a long recording gets scattered into it, interleaved with photos and whatever else the filesystem placed there.

The carver dutifully copies from the header onward and produces a file that's the first fragment followed by unrelated data. The player opens it, decodes until the first fragment boundary, then freezes — or refuses to open at all, because the container's index never turned up. The general limits of carving are catalogued in what PhotoRec can and cannot recover; fragmented video is the canonical case where it can't.

The root cause is simple: the ordering of clusters lived in the filesystem's allocation structures, and those are gone. No carver can extract information that no longer exists. The only remaining copy of the ordering is implicit — in the content of the clusters themselves — and that's what this method reconstructs.

The method: rebuild the ordering from content

Picture assembling a jigsaw puzzle from several boxes that got mixed together, with no reference picture. You can only match edges piece by piece, and you're only sure the picture is right once every piece forms a scene that makes sense. This method's four stages work on the same logic, run as a pipeline over the image.

Classify every cluster. A census of the whole image at allocation-unit granularity, tagging each cluster by content type: video bitstream, JPEG data, filesystem metadata, blank. The classifiers are magic bytes where they exist, entropy where they don't, and codec-structure checks in between — a cluster of H.264 video isn't random bytes, it has NAL-unit syntax that either parses or doesn't. The output is a map of every cluster that could belong to the footage, and every cluster that certainly doesn't.

Score candidate joins. Contiguous runs of same-class clusters form fragments. The question becomes which fragment follows which. Each candidate boundary is scored on whether the stream continues legally across it: decoder state carried over the join without violation, embedded timestamps and counters incrementing plausibly, and a locality prior — fragments of one file tend to land near each other on flash, so nearby candidates rank ahead of distant ones.

The scorer keeps the top few successors per fragment, not just the best one. It's a hypothesis generator, not a judge.

Assemble candidate orderings. Fragments chain best-first into a full candidate file: pick the strongest available join, extend, continue until the chain reaches an end-of-stream marker or stalls.

Verify globally, then unwind. This is the stage that separates the method from wishful concatenation. A candidate assembly is judged as a whole: decode it end to end and correlate the decoded output against independent evidence. The embedded preview thumbnails most recording devices write into their files are the strongest witness, because a preview is tiny but spans the entire recording.

An assembly that passes is kept and its clusters leave the pool. An assembly that fails is unwound: every cluster returns to the pool, the hypothesis is marked dead, and the next candidate ordering is tried. Rounds repeat as the pool thins, and the process stops when a round keeps nothing new.

Loading diagram…

Why global verification beats local confidence

The design principle underneath deserves stating on its own, because it applies beyond recovery too. A join score looks at a few kilobytes on either side of a boundary — it's information-starved by construction. Two fragments from different files can look perfectly compatible at that scale, and dark scenes or flat content give almost no signal at all.

Raising the local threshold doesn't fix this. It just starves the pipeline until nothing passes, and you end the day with high-confidence nothing.

The working inversion: accept permissively at the local level — a sanity floor, nothing more — and be ruthless at the global level, where the verdict is backed by hundreds of frames of evidence instead of a few kilobytes. Make unwinding cheap, and wrong local guesses cost only a rejected assembly, never a corrupted result.

Then iterate: hypothesize, assemble, verify, unwind, until the video plays end to end and the verifier has nothing left to object to. Per-fragment certainty was never achievable. Whole-file certainty is.

What it costs, and when it's justified

Honesty about cost belongs in the method. The cluster census and join scoring are compute across the entire image. The verification loop runs in rounds that each take real time.

The tooling is partly custom per case, because cameras, codecs, and container layouts differ. This is days of work, not hours, and it needs an engineer comfortable inside codec internals.

That price is justified in exactly one situation: footage that can't be re-shot — one-off events, the only recording of a person, or material with legal weight. For replaceable data, the correct answer is a backup or accepting the loss.

In every case, the cheap insurance is behavioral: the moment loss is discovered, stop writing to the drive — every new write overwrites clusters this method needs — image it, and work only on the image.

The takeaway

"The recovery software found my video but it won't play" is fragmentation, almost every time. The ordering information lived in the filesystem and died with it, so it has to be rebuilt from the content itself: classify, score, assemble, verify globally, unwind what fails.

Trust whole-file evidence over fragment-level confidence, and keep iterating until the footage plays end to end. It's slow. It's expensive. But for footage that exists nowhere else, it's the difference between a directory of broken files and the recording back in your hands.

Related Posts

Building something similar?

Hotel Management System Development

Custom ERP-style hotel management software: bookings, room status, invoicing, staff, and WhatsApp automation — built around how your hotel actually runs.

See how I can help