What Instagram counts as 9:16
Nine sixteenths is 0.5625. Exactly, with nothing left over. A 1080x1920 frame is exactly 0.5625, and that is the full-screen 9:16 the ads tools ask for. A 1079x1919 frame is 0.56227. Nobody can see the difference: on a phone the two clips are indistinguishable, and no one you show them to will guess which is which.
The check on the ads side is not "looks vertical" though. It compares numbers, and it has no tolerance wide enough for your one pixel. So a Reel that uploaded fine, looks fine and collects views fine gets refused at the boost button, and the refusal never tells you what ratio it found.
Where 1079x1919 comes from
If the video was assembled in a browser-based editor, it was most likely recorded off a canvas: the page draws each frame, and the recorder captures that canvas as it is. That is where the extra pixel nobody ordered appears.
The on-screen canvas is the board size multiplied by the view scale. Before recording, the scale is set to one so the capture happens at full resolution, and the usual way to do that is "current scale times its own reciprocal". In arithmetic that is one. In binary floating point, a number times its reciprocal is not always exactly one; sometimes it is 0.9999999999999998. The canvas is then asked for a width of 1079.9999999999998, and canvas.width is an integer: the fraction is dropped and the file comes out 1079 wide.
An odd number has a second consequence. H.264 with 4:2:0 chroma subsampling wants even sides, so that 1079 has to go somewhere: the encoder either refuses the job or quietly moves an edge. You want neither, and both happen after the file already looked finished.
How to check your own file
The check takes ten seconds and answers the question Instagram's interface will not: what shape is this file, really.
How to fix the aspect ratio
If the file is not 9:16 it has to be rebuilt, and the only real choice is what you are willing to lose. Fitting keeps the whole picture and adds bars, so the subject gets smaller. Filling uses the whole frame and cuts the edges, so nothing shrinks.
The force_original_aspect_ratio option in the scale filter does the work: decrease guarantees the picture fits whole and leaves room for the bars, increase guarantees both sides reach the target so the crop never reads past the edge of the frame. The publishing requirements for Reels are in the Instagram Platform docs; the promotion rule is not there, it lives in the app and shows up only at the moment of refusal.
Why an extra re-encode breaks 9:16 by itself
The other side of it: a file that is already exactly 1080x1920 should not be touched at all. Pipelines that run everything through a normaliser "just in case" often pick their own output resolution when no size is given, so a correct 9:16 becomes an almost-9:16 after it was already made properly, and the search for the cause starts in the editor.
The rule is simple: normalise only what actually needs it. If the video is already H.264 and already the exact size, the most useful thing a service can do is hand the file over untouched. Same idea as in our piece on face and voice in generated video: every extra processing step changes something, and not always the thing you meant to change.
That last step is the first place the rule is ever stated. Which is why the size is worth checking at step one: ten seconds against re-uploading a Reel that has already gathered its reach. For the other places where Instagram refuses without explaining, we wrote a separate piece.
Short checklist
How we handle it
This article grew out of our own bug: the editor handed over 1079x1919 and swore it was 9:16. The recording size now comes from the board alone and depends on neither the zoom nor the size of the window.
5 minHow to create an AI influencer: what the job actually is
5 minLLM cost per request: what 204 production calls actually cost
11 minHow to create an AI model for Instagram and TikTok: face swap video, voice clone, first clip step by step