What moov atom not found Means

An MP4 file is made of blocks called “atoms” (also called “boxes”). Two of them matter here:

  • mdat (media data): the video and audio themselves
  • moov (movie): the index, with the timestamps and the position of every sample in the file

Without the moov atom, neither a player nor FFmpeg can read the file.

Example error:
moov atom not found
Invalid data found when processing input

Why the moov Atom Ends Up at the End of the File

By default, FFmpeg writes the moov atom at the end of the file, after encoding has finished. While it is still encoding, it does not know how big mdat will be, so it cannot yet fill in the position (offset) of each frame that moov stores.

[Default structure]
ftyp | mdat (huge video/audio data) | moov (index)

This layout causes two problems:

  1. Web playback starts late. If the server supports HTTP range requests (requests for part of a file), the player fetches the moov atom from the end first. Playback does not wait for the whole download, but it starts later.
  2. A crash leaves a broken file. If recording stops before moov is written, the file has no moov atom at all.

Moving moov to the Front: -movflags faststart

When FFmpeg writes an MP4 with -movflags faststart, it puts the moov atom at the start of the file. With -c copy, this works on an existing file without re-encoding:

ffmpeg -i input.mp4 -c copy -movflags faststart output_fast.mp4

With the index first, a browser can start playing the video before the whole file has downloaded.

[faststart structure]
ftyp | moov (index) | mdat (video/audio data)

Specifying faststart During Encoding

If you are re-encoding anyway, add the flag to the same command:

ffmpeg -i input.mp4 -c:v libx264 -crf 23 -c:a aac -movflags faststart output.mp4

Optimizing an Existing File with qt-faststart

qt-faststart is a small program in the tools/ folder of the FFmpeg source code. It also moves the moov atom of an existing MP4 to the front. The gyan.dev Windows builds do not include it.

qt-faststart input.mp4 output_fast.mp4

It does not re-encode anything. It only moves the moov atom, so it is fast and loses no quality.

Repairing a File Broken by a Recording Crash

FFmpeg alone cannot repair a file that lost its moov atom because recording stopped early. If you have a good file recorded on the same device with the same settings, the open-source tool untrunc can sometimes rebuild the moov atom from it.

untrunc ok.mp4 broken.mp4

ok.mp4 is the good file and broken.mp4 is the damaged one. If the repair works, you get broken_fixed.mp4.

Commercial Tools

  • Remo Video Repair
  • Stellar Video Repair

Fragmented MP4 for Better Crash Resilience

For recordings, a fragmented MP4 holds up better when something crashes. It writes an empty moov atom at the start, then adds the media in short fragments (each one a moof + mdat pair):

ffmpeg -i input.mp4 -c copy \
  -movflags frag_keyframe+empty_moov+default_base_moof \
  -frag_duration 4000000 \
  output_frag.mp4
  • frag_keyframe: starts a new fragment at each keyframe
  • empty_moov: writes an empty moov atom at the start of the file
  • default_base_moof: sets the default-base-is-moof flag in tfhd, so the data positions in each fragment are counted from its own moof
  • -frag_duration 4000000: makes each fragment at most 4 seconds long (the value is in microseconds). frag_keyframe can start the next fragment earlier, at a keyframe

If a crash happens partway through, the part already written can still be played. The layout is close to HLS/DASH segments.

Measured: time and size

The measured command:

ffmpeg -i input.mp4 -c copy -movflags +faststart output.mp4
Metric Measured
Wall time 0.49 s (242.58x realtime)
Output size 353.29 MB

Test machine: Core i9-14900KF (32 threads), FFmpeg 8.1 (gyan.dev). Source: an MP4 made from a 1920x1080, 30 fps, 120 s, 351.4 MB video (Big Buck Bunny, looped, CC BY 3.0) plus one 128 kb/s AAC audio track, 353.29 MB in total. Measured 2026-09-05, one run at a time. The raw numbers are in the dataset.

Why it is so fast

Two minutes of video took half a second (242.58x realtime) because nothing is encoded. With -c copy, FFmpeg reads the compressed packets, writes them back out unchanged, and moves the moov atom from the end of the file to the front, updating the offsets as it goes. The work is reading and writing the file plus rewriting the index, so the CPU has little to do.

For comparison, on the same machine and source, a plain re-encode with no filter (-c:v libx264 -crf 23 -preset medium) took 27.97 s, and a VP9 transcode took 729.16 s. Other jobs that copy the video finished close to faststart: a -map 0 -c copy stream copy took 0.41 s, and an afade pass that re-encodes only the audio took 1.03 s. What decides the runtime is whether the video is re-encoded.

The time depends on file size and storage speed: 0.49 s for a 353.29 MB file here. A 2 GB file, or a file on a network drive, takes proportionally longer. A higher resolution or a heavier codec does not make it slower.

The output is 353.29 MB, the same size as the input: -c copy passes the streams through untouched, and faststart only moves the moov atom. The difference from the 351.4 MB video is the audio track. Comparing this size with a re-encoded file tells you nothing, so read the time instead.

This command cannot repair a file that has no moov atom after a crash. faststart only rearranges a valid MP4; recovering a broken one is a separate job.

For video you publish on the web, add -movflags +faststart to the encoding command so you do not need a second run. If you forget, adding it afterwards took 0.49 s here.

How to Inspect the Atom Structure of an MP4

ffprobe can list the atoms in the order they appear in the file:

ffprobe -v trace -i input.mp4 2>&1 | grep -E "type:'(ftyp|moov|mdat)'"

If moov comes before mdat, the index is already at the front.

Frequently Asked Questions

Q: Can I just re-encode a file that gives moov atom not found?

No. Without the moov atom, FFmpeg cannot tell where the frames are, so it cannot read the file at all. Repair it with a tool such as untrunc first.

Q: Should I always use -movflags faststart?

Use it for video that plays on the web or streams. Files you only play locally do not need it. For recording, frag_keyframe+empty_moov survives crashes better.

Q: How long does faststart take to process?

It does not re-encode the file, so it is very fast (within a few seconds).