fix(build): fall back to a mirror when ffmpeg.org refuses the runner - #226
Merged
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
The macOS x64 leg of v1.8.0-rc.6 died on the ffmpeg tarball fetch, twice,
twenty minutes apart:
curl: (35) Recv failure: Connection reset by peer
This is not congestion and not a bad pin. In both runs the arm64 leg on
`macos-latest` fetched the same tarball from the same host with the same cold
cache and succeeded, while the x64 leg on `macos-15-intel` was reset about a
second after starting. An immediate reset that reproduces on one runner pool
and never on the other is an egress-level block, so no amount of retrying
clears it — a first attempt at this shipped only `--retry-all-errors` and would
not have fixed the build.
So the source list grows a second entry. Debian's `.orig.tar.xz` is the upstream
tarball unmodified — verified byte-identical to the pinned sha256 — and
deb.debian.org is CDN-backed. Each source is tried in turn and must both
download and match the checksum; the checksum is what makes a second origin safe
to trust, and it gates every source equally. Nothing is downgraded: ffmpeg.org
stays first, and a mirror that lacks a future version is skipped rather than
fatal.
Three flags carry their own reasons:
- `--retry-all-errors`, because curl only auto-retries what it classes as
transient (timeouts, 429, 5xx) — not a reset, not a handshake failure, which
are exactly the errors seen here. Verified against a refused connection:
`--retry 2 --retry-delay 1` gives up after 0s, adding `--retry-all-errors`
spends 2s retrying.
- `--connect-timeout 20`, because a throttled origin hangs rather than refuses.
Measured: after a few rapid fetches ffmpeg.org left a connect sitting for 75s
before failing. Times four attempts, that is five minutes burned before the
second source is even tried.
- `-f`, so an HTTP error page is not written to the tarball and resurfaced as a
checksum mismatch, which reads like a moved pin rather than a bad response.
Exercised by extracting the function and running it against real endpoints:
canonical alone succeeds; a dead first source falls through to Debian; a source
serving the wrong bytes (ffmpeg 8.1.1) is rejected on checksum and the next one
is used; and with every source broken it throws listing each attempt with its
reason — curl status or the actual hash.
The sibling `scripts/fetch-ffmpeg.mjs` has the same single-source shape at line
359 but is left alone: it is the Windows/Linux path, pulls from GitHub releases
rather than ffmpeg.org, and uses node's fetch rather than curl.
EtienneLescot
force-pushed
the
fix/ffmpeg-fetch-retry
branch
from
August 1, 2026 14:59
3d35453 to
c1d204f
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The macOS x64 leg of the v1.8.0-rc.6 build dies on the ffmpeg tarball fetch:
This is an egress-level block, not congestion and not a bad pin. The evidence is in the two attempts of that run:
macos-latest)macos-15-intel)Both legs had the same cold cache and fetched the same tarball from the same host. One pool works, the other is reset immediately, and it reproduces twenty minutes apart. Retrying does not clear that — an earlier version of this PR added
--retry-all-errorsalone and would not have fixed the build.The pin itself is fine:
ffmpeg.orgserves bytes matchingTARBALL_SHA256exactly, verified locally.The fix
A second source. Debian's
.orig.tar.xzis the upstream tarball unmodified — verified byte-identical to the pinned sha256 — anddeb.debian.orgis CDN-backed:Each source must both download and match the checksum before it is used. The checksum is what makes trusting a second origin safe, and it gates every source equally — nothing is downgraded. ffmpeg.org stays first, and a mirror that does not yet carry a future version is skipped rather than fatal.
Three flags carry their own reasons, none of them decoration:
--retry-all-errors— curl only auto-retries what it classes as transient (timeouts, 429, 5xx). That does not include a connection reset or a TLS handshake failure, which are exactly the errors here.--retry 3alone is the obvious-looking fix and would have done nothing.--connect-timeout 20— a throttled origin hangs rather than refuses. Measured: after a few rapid fetches, ffmpeg.org left a connect sitting for 75 seconds before failing. Times four attempts, that is five minutes of build time burned before the second source is even tried.-f— keeps an HTTP error page from being written to the tarball and resurfacing as a checksum mismatch, which reads like a moved pin rather than a bad response.Related issue
None — found from the rc.6 build failure.
Type of change
Release impact
CI reliability only; nothing in the shipped app changes. This is what unblocks a macOS release —
publish-releaseneedsbuild-macos, so rc.6 has not published.Desktop impact
Screenshots / video
n/a — build script.
Testing
downloadTarballwas extracted from the file and run against real endpoints, so this exercises the shipped code rather than a retelling of it:The failure message from the last case:
Retry behaviour verified separately, against a refused connection — the same class of failure as a reset:
Also:
--retry-all-errorsneeds curl ≥ 7.71 (2020) and macOS runners ship 8.x;node --checkandbiome checkclean.Not tested: the script end to end, which builds ffmpeg from source (~5 min) and writes into
crates/thirdparty/. The change is confined to how the tarball is obtained; everything downstream of the checksum is untouched. The x64 leg of the next macOS build is the real proof — and it is the case that currently fails, so it will be obvious either way.Out of scope
scripts/fetch-ffmpeg.mjs:359has the same single-source shape (await fetch(url), no retry) but is deliberately left alone: it is the Windows/Linux path, pulls from GitHub releases rather thanffmpeg.org, and would need a different fix since it uses node'sfetch. Worth a follow-up if that path ever flakes — though GitHub is not the origin causing trouble here.If the block turns out to be permanent rather than a reputation-based throttle, the sturdier move is to stop depending on a third-party origin at build time at all: publish the pinned tarball as an asset on an internal release, the way
stage-whisper-stt.shalready does for the whisper binaries. That is a bigger change and this one is enough to unblock the release.