When you work with recorded files, downloaded streams, or concatenating multiple files, have you ever had FFmpeg suddenly halt with the error Application provided invalid, non monotonically increasing dts to muxer, or churn out a flood of warnings while the output file plays back with stutters? These problems all stem from inconsistencies in the timestamps (PTS/DTS). This article first clarifies what the error means, then walks through four repair commands tailored to different situations.
Tested with: FFmpeg 6.1 (verified against real FFmpeg)
What You Will Learn
- What the messages mean —
non monotonically increasing dts/invalid PTS/DTS - The typical causes of broken timestamps (VFR sources, discontinuous timestamps, concat, interrupted recordings, and more)
- Four repair approaches for different situations
- Regenerate timestamps with
-fflags +genpts - Shift negative timestamps to a zero origin with
-avoid_negative_ts make_zero - Convert VFR (variable frame rate) to CFR (constant) with
-fps_mode cfr - Align the start to zero with
setpts/asetpts
- Regenerate timestamps with
- How to tell the cases where
-c copyfixes it (just re-tagging) apart from the cases that require re-encoding (VFR→CFR, etc.)
What the Error Means and Why It Happens
Common Messages
[mp4 @ 0x...] Application provided invalid, non monotonically increasing dts to muxer in stream 0
Invalid timestamps stream=0, pts=..., dts=..., size=...
Non-monotonous DTS in output stream 0:0; previous: ..., current: ...; changing to ...
What PTS and DTS Are
- PTS (Presentation Time Stamp) … the time indicating when a frame should be displayed
- DTS (Decoding Time Stamp) … the time indicating when a frame should be decoded
The muxer operates on the assumption that each stream’s DTS is monotonically increasing — that is, that the time always advances beyond the previous frame. When a DTS equal to or earlier than the previous frame is passed in, the non monotonically increasing dts error occurs.
In a normal video the timestamps of each frame increase cleanly, so this error never appears. But when an interrupted recording, a stream concatenation, or a source with uneven frame intervals is involved, the ordering of the timestamps gets disturbed, or the times jump backward and forward when a missing section is filled in after the fact. The muxer treats such “time-rewinding” input as data with broken consistency, and reports it as an error or warning. Note that even though dts is shown in the message, the root cause is often corruption on the PTS side, so in practice it is best to think of the two together.
Main Causes
| Cause | Description |
|---|---|
| VFR (variable frame rate) sources | Phone recordings, screen captures, game streams, and the like have non-uniform frame intervals. They easily diverge from the timestamps the muxer expects |
| Broken / discontinuous timestamps | TS streams or partially downloaded files lose PTS/DTS or cause them to rewind |
| Concatenating different streams | Joining separately recorded files as-is makes the start of the second file fall back near 0, producing a DTS in the past |
| Interrupted recordings | When a stream capture or recording is cut off midway, the trailing timestamps get corrupted |
| Negative timestamps | In conversions such as TS→MP4, the start begins from a negative time, which the muxer dislikes |
Depending on the cause, it varies whether you can fix it “just by re-tagging (-c copy)” or whether you need to “reorder the frames = re-encode.” Let’s look at each in turn below.
Fix 1: Regenerate with genpts
This is the first method to try in cases where only the PTS/DTS are missing or corrupted while the frames themselves are intact. Adding -fflags +genpts makes FFmpeg estimate and regenerate the missing or broken PTS from the frame rate and container information.
ffmpeg -fflags +genpts -i input.mp4 -c copy output.mp4
-fflags +genpts— the flag that generates (generate PTS) timestamps. Place it before-ibecause it applies to the input side-c copy— copy video and audio without re-encoding. Lossless and fast
This is the lightest method that can resolve many non monotonically increasing dts cases without re-encoding. Try this first, and move on to the next step only if warnings still remain.
The reason you should try this first is that regeneration merely rebuilds the container’s timestamp information and does not touch the video or audio data itself at all. Combined with -c copy, it finishes in a few seconds with zero loss of picture or sound quality. The majority of files where “the contents are intact but only the timestamp information is suspect” — such as downloaded TS files or stream captures — become playable again with this single step. Conversely, if this does not fix it, it is a sign that the problem lies not in the “values” of the timestamps but in “the ordering of the frames themselves,” which becomes the basis for moving on to the VFR→CFR conversion described later.
Tip:
-fflagsis a flag for the input file, so always write it before-i input.mp4. If you put it after, it is interpreted as an output-side flag and has no effect.
Fix 2: Correcting Negative Timestamps
When you convert a .ts (MPEG-TS) file to MP4 or similar, if the start of the stream begins from a negative time, the muxer may reject it or the playback start position may shift. -avoid_negative_ts make_zero pulls this toward a zero origin.
ffmpeg -i input.ts -c copy -avoid_negative_ts make_zero output.mp4
-avoid_negative_ts make_zero— when the origin of the timestamps would be negative, shift everything so that the minimum value becomes 0-c copy— no re-encoding. Since it only shifts timestamps, it is lossless
make_zero does not “set the first frame’s timestamp to 0” but rather “aligns the smallest timestamp to 0 and translates everything in parallel.” It is effective for symptoms such as the A/V heads being offset or the head being clipped during conversion from TS.
MPEG-TS is a format designed for broadcast waves and streaming, and it has its own reference time called PCR (Program Clock Reference). Because of this, when you move it into a container that assumes a zero origin like MP4, the start tends to become a negative value. If you leave the negative timestamps as-is when making the MP4, depending on the player the very beginning may not play, or the heads of audio and video may be slightly offset. Aligning the origin with make_zero heads off these differences between playback environments before they happen.
Using It Together with genpts
In a case where the timestamps are broken and there is also a negative origin, you can specify both at once.
ffmpeg -fflags +genpts -i input.ts -c copy -avoid_negative_ts make_zero output.mp4
This is a two-stage approach: rebuild the PTS with -fflags +genpts (input side), and pull the origin toward 0 with -avoid_negative_ts make_zero (output side). This combination is the standard for repairing TS files.
Fix 3: Converting VFR to CFR
If the -c copy methods so far don’t fix it, the cause is usually VFR (variable frame rate). Because the frame intervals of a VFR source are themselves uneven, re-tagging alone won’t stabilize it; you need to reorder the frames at a constant interval = re-encode.
ffmpeg -i input.mp4 -fps_mode cfr -r 30 -c:v libx264 -preset veryfast -c:a aac output.mp4
-fps_mode cfr— make the output CFR (constant frame rate). Frames are duplicated or dropped as needed to even out the spacing-r 30— specify a target frame rate of 30 fps (change to24,25,60, etc. to match the source)-c:v libx264— the video is re-encoded because the frames are reordered (copy is not possible)-preset veryfast— balances encoding speed and quality-c:a aac— the audio is re-encoded as AAC
VFR-induced symptoms such as “stuttering playback,” “audio drift in editing software,” and “the muxer firing off repeated DTS warnings” can often all be resolved together by converting to CFR.
VFR is an excellent mechanism in terms of recording efficiency, but because the frame intervals are not constant, it sits poorly with editing software and some players that assume a fixed frame rate, making it a breeding ground for trouble. In CFR conversion, gaps are filled by duplicating frames and dense regions are thinned out, so that all frames are reordered at equal intervals. As a result the timestamps also increase regularly, and the DTS warnings disappear at the root. It is safest to match the target fps to roughly the source’s frame rate: choose 30 for phone recordings, 24 for cinematic material, and 60 for game streams. Note that specifying a higher fps than the original needlessly bloats the file size, while too low a value makes motion coarse.
For older FFmpeg:
-fps_modeis a relatively new option. It may not be available in older builds, in which case use the traditional-vsync cfrinstead (ffmpeg -i input.mp4 -vsync cfr -r 30 -c:v libx264 -c:a aac output.mp4). The behavior is equivalent.
Fix 4: Resetting with setpts/asetpts
When “the starting time does not begin from 0” or “the times have shifted due to trimming or joining,” the filters setpts / asetpts re-align the timestamps to a zero origin at the start.
ffmpeg -i input.mp4 -vf setpts=PTS-STARTPTS -af asetpts=PTS-STARTPTS -c:v libx264 -c:a aac output.mp4
-vf setpts=PTS-STARTPTS— subtract the starting PTS (STARTPTS) from each video frame to reset the start to 0-af asetpts=PTS-STARTPTS— perform the same processing on the audio side (the one withais for audio)-c:v libx264/-c:a aac— sincesetpts/asetptsare filters, applying them requires re-encoding
setpts is a video filter and asetpts is an audio filter; always specify them as a pair to align the origins of video and audio. Whereas genpts “estimates and creates broken values,” setpts=PTS-STARTPTS differs in that it “leaves the existing values as-is and only translates the origin to 0.”
When -c copy Fixes It vs. When Re-Encoding Is Required
The most important thing in choosing a repair command is determining whether re-encoding is necessary.
| Situation | Appropriate Fix | Re-encoding |
|---|---|---|
| PTS/DTS are merely missing or corrupted | -fflags +genpts + -c copy | Not needed |
| Negative timestamps at the start (TS conversion, etc.) | -avoid_negative_ts make_zero + -c copy | Not needed |
| VFR source with uneven intervals | -fps_mode cfr -r N (recompress with libx264, etc.) | Required |
| Want to re-align the start to a zero origin | setpts=PTS-STARTPTS / asetpts=PTS-STARTPTS | Required (because they are filters) |
The decision flow is simple.
- First try the light
-c copyoptions (genpts, avoid_negative_ts). If this fixes it, you finish losslessly and fast - If warnings still don’t disappear or playback is unstable, suspect VFR and re-encode with
-fps_mode cfr - If the times are merely shifted after trimming or joining, reset with
setpts/asetpts
Because -c copy copies the bitstream as-is and only rewrites the container’s tags, there is zero quality degradation, but it cannot change the ordering of the frames themselves. VFR→CFR conversion and filter application, which require thinning, duplicating, and reordering frames, cannot in principle be achieved with copy and require re-encoding.
Tested Versions / Target OS
Tested with: FFmpeg 6.1 (verified against real FFmpeg) Target OS: Ubuntu 24.04 / macOS / Windows (the commands are common across all) On older builds where
-fps_modeis unavailable, you can substitute-vsync cfr.
FAQ
Q1. The warnings don’t disappear even after adding -fflags +genpts
It’s highly likely the source is VFR. genpts only estimates and regenerates the timestamps; it does not even out the frame intervals themselves. Try converting to a constant frame rate with -fps_mode cfr -r 30 (Fix 3). Also, since -fflags is an input flag, double-check that you have placed it before -i.
Q2. How do -avoid_negative_ts make_zero and setpts=PTS-STARTPTS differ?
-avoid_negative_ts make_zero is an output option that pulls the timestamp origin toward 0 at the container (muxer) level, and it can be used while keeping -c copy. setpts=PTS-STARTPTS is a filter that rewrites the PTS of each frame, so it requires re-encoding. The basic distinction is to first try the lightweight avoid_negative_ts, and use setpts when you want to set a zero origin as part of a filter chain.
Q3. I get non monotonically increasing dts after joining with concat
A typical example: when you concatenate separately recorded videos, the starting timestamp of the second and later files falls back into the past, breaking the monotonic increase of the DTS. When joining with the concat demuxer, either use -fflags +genpts together, or run the joined result through the repair commands in this article to stabilize it. For the joining procedure itself, also see the related article Concatenating Multiple Videos.
Q4. I’m told the -fps_mode option doesn’t exist
Your FFmpeg may be old. -fps_mode is a relatively new option name, and before it -vsync served the same role. Replace -fps_mode cfr with -vsync cfr and run it. If possible, check ffmpeg -version and consider updating to a newer build as well.
Related Articles
- FFmpeg Common Errors and Fixes
- Changing the Frame Rate of a Video
- Fixing Audio/Video Sync
- Concatenating Multiple Videos
Tested with: ffmpeg 6.1.1 / Ubuntu 24.04
Primary sources: ffmpeg.org/ffmpeg.html / ffmpeg.org/ffmpeg-filters.html / trac.ffmpeg.org/wiki/ChangingFrameRate