curl Download a Release Asset (GitHub)
Release downloads redirect to a CDN and may need auth, so a couple of flags are essential.
Pulling a binary or archive from a GitHub release is common in pipelines. The public path is easy; private repos and the API path need a bit more.
What it does
GitHub exposes public release assets at a predictable URL that redirects to a CDN, so you need -L. For private repos you authenticate against the API and request the asset with Accept: application/octet-stream, which also redirects. In both cases -f turns a 404 into a failed step rather than a saved error page.
Common usage
# public: latest release asset (redirects to a CDN)
curl -fL -o app.tar.gz \
https://github.com/owner/repo/releases/latest/download/app.tar.gz
# private: via the API with a token
curl -fL -o app.tar.gz \
-H "Authorization: Bearer $GITHUB_TOKEN" \
-H 'Accept: application/octet-stream' \
https://api.github.com/repos/owner/repo/releases/assets/123456Flags
| Flag | What it does |
|---|---|
| -L | Follow the redirect to the CDN that serves the asset |
| -f | Fail on 404 instead of saving an error page |
| -o <file> | Name the downloaded file |
| -H 'Accept: application/octet-stream' | Ask the API for the binary, not JSON |
| -H "Authorization: Bearer $T" | Authenticate for private repos |
In CI
Always use -fL for release downloads. Without -L you save the redirect page; without -f a typo in the asset name silently saves a 404 HTML page that later breaks tar or unzip. For private assets you must hit the API asset id, not the browser download URL.
Common errors in CI
gzip: stdin: not in gzip format after extracting usually means you saved a 404 page because -f or the asset name was wrong. A 404 from the API on a private repo means the token lacks repo scope or the asset id is wrong.