Skip to content
Latchkey

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

Terminal
# 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/123456

Flags

FlagWhat it does
-LFollow the redirect to the CDN that serves the asset
-fFail 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.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →