X's media documentation states one pixel format and gives no alternative: "Pixel format: Only YUV 4:2:0 is supported." That single line, buried in the Advanced section of the developer docs, is the official basis for rejecting a file that is otherwise the right size, the right length and the right codec.
Nothing in your file name tells you which chroma subsampling an export used. The fix is one flag — but knowing why you need it is what stops you from spending an afternoon re-compressing a file whose size was never the problem.
The command
ffmpeg -i input.mov \
-c:v libx264 -profile:v high -pix_fmt yuv420p \
-vf "scale=1280:720:force_original_aspect_ratio=decrease,setsar=1" \
-r 30 -b:v 5000k \
-c:a aac -ac 2 -b:a 128k \
-movflags +faststart out.mp4X does not publish FFmpeg commands. It describes the file it wants, and the flags above are how FFmpeg expresses that description. Where FFmpeg's own behaviour on your build is the question, FFmpeg's documentation is the answer — this page only claims to be accurate about what X wrote.
First, check what you actually have before you re-encode anything:
ffprobe -v error -select_streams v:0 \
-show_entries stream=pix_fmt,field_order,sample_aspect_ratio \
-of default=noprint_wrappers=1 input.movIf pix_fmt already reads yuv420p, the pixel format is not your problem and you should stop reading at the troubleshooting section below.
What each flag does, and which line it comes from
X's developer documentation splits its video guidance into Recommended (what to aim for) and Advanced (hard constraints written with "must"). The difference matters, so here is each flag with the line behind it.
| Flag | X's line (verbatim) | Section |
|---|---|---|
-pix_fmt yuv420p | "Pixel format: Only YUV 4:2:0 is supported" | Advanced |
setsar=1 | "Pixel aspect ratio: must have 1:1" | Advanced |
-c:v libx264 -profile:v high | "Video Codec: H264 High Profile" | Recommended |
-r 30 | "Frame Rates: 30 FPS, 60 FPS" | Recommended |
-c:a aac -b:a 128k | "Audio Codec: AAC LC" · "Minimum Audio Bitrate: 128 kbps" | Recommended |
-ac 2 | "Audio must be mono or stereo, not 5.1 or greater" | Advanced |
scale=1280:720 | "Video Resolution: 1280x720 (landscape), 720x1280 (portrait), 720x720 (square)" | Recommended |
Three of those need more than a table row.
-pix_fmt yuv420p is the only one with no wiggle room. The Advanced section's wording is absolute — "Only YUV 4:2:0 is supported" — where every neighbouring line is phrased as a range or a recommendation. X's ads documentation uses the same number from the other direction: "Video codec recommendation: H264, Baseline, Main, or High Profile with a 4:2:0 color space." Two separate X properties, one chroma format.
-b:v 5000k is where X disagrees with itself on the same page. The Recommended block says "Minimum Video Bitrate: 5,000 kbps". Further down, the same page carries an upload table whose landscape 1280x720 row reads 2048K — and that table is introduced with "In the table below each row represents an upload recommendation, but is not a requirement." So the page gives you two different numbers for the same resolution. Both are official; neither is a hard limit. Use 5000k if you want to satisfy the stated minimum, and treat the table as the lower-bandwidth option.
Two Advanced lines have no flag in the command above, because whether you need them depends on your source: "Must not have open GOP" and "Must use progressive scan". FFmpeg exposes a closed-GOP flag and several deinterlacing filters; whether your build already produces a closed GOP by default is a question for ffmpeg -h encoder=libx264, not a thing to assume. The ffprobe command above prints field_order so you can see whether deinterlacing is even relevant.
Why the rejection tells you nothing
Here is the part that makes this bug expensive. X's documentation states these constraints with "must" — and never states what error you get when you violate one. There is no published mapping from "4:4:4 source" to any specific message.
What X does say, in its ads upload help, is this, verbatim:
"Even if your file is under our maximum size, we may still have issues ingesting the file."
That sentence is the official acknowledgement that a file inside every published limit can still fail. The same page's checklist asks you to "Confirm your video is within our required specifications. Does your video file have the correct video and audio codecs? the right frame rate? is your file too large?" — note that size is the last of four questions, not the first.
Media Studio's help page is equally broad about its own "Upload failed" message: "This error can appear for a few different issues: file size, resolution, encoding settings, or a connection issue." Pixel format falls under "encoding settings", and that is as specific as X gets.
So the diagnostic order is inverted from what people actually do. Most users re-compress to shrink the file, the upload fails again, and they conclude X is broken. If the file was already under the cap, shrinking it changes nothing about a constraint that was never about bytes. Run ffprobe first. For the size-related failure modes, why X uploads fail covers the other branch.
Variations
Keep the source resolution. Drop the scale filter but keep setsar=1, and check your dimensions against the constraint that applies to you — the developer docs say "Dimensions: must be between 32x32 and 1280x1024", while the help centre's FAQ about uploading on the web lists a maximum of 1920 x 1200 (and 1200 x 1900). Those are two different official answers with two different scopes; pick the one matching how you upload.
Fix the pixel format only, leave audio alone:
ffmpeg -i input.mov -c:v libx264 -profile:v high \
-pix_fmt yuv420p -c:a copy -movflags +faststart out.mp4Only safe if your audio already satisfies the Advanced line: "Audio must be AAC with Low Complexity profile. (High-Efficiency AAC is not supported)". HE-AAC passes through -c:a copy untouched and stays non-compliant.
Vertical or square: swap the scale target for 720:1280 or 720:720, both named in the Recommended list.
If you would rather not install FFmpeg
For a one-off clip, the same re-encode runs in a browser tab:
Try it right here
Runs in your browser. Your file is not uploaded anywhere.
It passes -pix_fmt yuv420p and encodes audio as AAC, so a 4:2:2 or 4:4:4 master comes back as 4:2:0 H.264 in an MP4 — the pixel-format problem and the file-size problem solved in one pass. Everything is read from disk and re-encoded locally, so unpublished footage never gets uploaded on the way to fixing an upload. What it will not give you is a switch for GOP structure or profile; for those, the command line is the right tool. The full list is at all Clapr tools.
Troubleshooting
ffprobe reports yuv420p and the upload still fails. Work down the other Advanced lines: pixel aspect ratio 1:1, no open GOP, progressive scan, AAC LC audio, mono or stereo. Any one of them can be the cause, and none of them is a size issue.
The file is a .mov and processing stalls. X's own advice for Media Studio is unambiguous: "This happens most often with .mov files. If possible, re-export files as .mp4, which should allow for overall faster upload and processing time." The command at the top of this page already outputs MP4; if you only need the container swapped, MOV to MP4 does it, and X uploads stuck processing has the longer version.
Your source is ProRes, 10-bit, or has an alpha channel. X's official documentation doesn't state how those are handled. Converting to 8-bit 4:2:0 H.264 satisfies the one rule that is published; anything beyond that is guesswork.
FAQ
What pixel format does X (Twitter) require for video?
X's media documentation states it in one line: "Pixel format: Only YUV 4:2:0 is supported." In FFmpeg that is -pix_fmt yuv420p.
Will X reject a 4:2:2 or 4:4:4 video?
X writes the requirement as "only" and does not list an exception. It also does not publish what error a non-conforming file produces, so you cannot diagnose this from the message you see — check the file with ffprobe instead.
How do I check the pixel format of my video?
ffprobe -v error -select_streams v:0 -show_entries stream=pix_fmt -of default=noprint_wrappers=1 input.mp4. If the answer is anything other than yuv420p, re-encode.
My video is well under the size limit and still will not upload. Why? X states directly that "Even if your file is under our maximum size, we may still have issues ingesting the file." Its checklist puts codecs and frame rate ahead of file size, and the Advanced constraints — pixel format, GOP, scan type, audio profile — are all independent of how large the file is.
Does -pix_fmt yuv420p hurt quality?
It discards chroma resolution relative to a 4:2:2 or 4:4:4 master, which is what the format change means. X allows nothing else, and its ads guidance names the same 4:2:0 color space, so there is no compliant alternative to weigh it against.
All X requirements quoted from the official X API media best-practices documentation, the X help centre, and X Ads upload help, checked 16 September 2026. These pages disagree with each other on several numbers and X revises them — verify before relying on any single figure. More command-line write-ups are in our ffmpeg guides.