Skip to content

fix(action): retry transport errors when downloading the release archive - #33

Merged
blairham merged 1 commit into
mainfrom
fix/curl-retry-all-errors
Aug 5, 2026
Merged

fix(action): retry transport errors when downloading the release archive#33
blairham merged 1 commit into
mainfrom
fix/curl-retry-all-errors

Conversation

@blairham

@blairham blairham commented Aug 5, 2026

Copy link
Copy Markdown
Owner

What

Add --retry-all-errors (and raise --retry 3 → 5) to the two curl calls in the install step.

-curl -fsSL --retry 3 -O "${base}/${archive}"
-curl -fsSL --retry 3 -O "${base}/checksums.txt"
+curl -fsSL --retry 5 --retry-all-errors -O "${base}/${archive}"
+curl -fsSL --retry 5 --retry-all-errors -O "${base}/checksums.txt"

Why

A consumer's CI run failed on its default branch with:

curl: (35) Recv failure: Connection reset by peer
##[error]Process completed with exit code 35.

curl --retry N only retries transient HTTP responses (5xx, 408, 429) and timeouts. A connection reset mid-transfer is a transport-level error, so curl exits 35 immediately and never touches its retry budget — --retry 3 was never going to cover this failure mode.

The run was otherwise green (test + build both passed); nothing was wrong with the repo or its hooks, and a plain re-run went green with no change. This step is pure infrastructure — fetch a tarball, verify its checksum — so an intermittent network fault should cost a retry, not a red check on someone's main.

--retry-all-errors requires curl 7.71+; GitHub-hosted runners ship 8.x.

Notes

  • Worst case adds ~31s per download before a real failure (curl's backoff doubles from 1s).
  • The checksum verification below is untouched — a truncated or corrupt download still fails loudly rather than being retried into a false pass.

The install step fetched the release archive with `curl -fsSL --retry 3`,
which only retries transient *HTTP* responses (5xx, 408, 429) and timeouts.
A connection reset mid-transfer is a transport-level error, so curl exited
35 immediately without ever using its retry budget:

    curl: (35) Recv failure: Connection reset by peer
    ##[error]Process completed with exit code 35.

That took down an otherwise-green CI run on a consumer's default branch —
nothing was wrong with the repo or its hooks, and a plain re-run went green
with no change. Since this step is pure infrastructure (fetch a tarball,
verify its checksum), an intermittent network fault should cost a retry,
not a red check.

`--retry-all-errors` (curl 7.71+, runners ship 8.x) extends the retry budget
to transport failures, which is the class we actually hit. Retries go 3 -> 5;
curl's backoff doubles from 1s, so the worst case adds ~31s per download
before failing for real, and the checksum verification below is unchanged —
a truncated or corrupt download still fails loudly rather than being retried
into a false pass.
@blairham
blairham merged commit 5e2ae68 into main Aug 5, 2026
5 checks passed
@blairham
blairham deleted the fix/curl-retry-all-errors branch August 5, 2026 01:34
blairham added a commit to pinpredict/.github that referenced this pull request Aug 5, 2026
… main (#51)

The push-to-default-branch run gates nothing. Its hook steps already end in
`|| true`, and the step that reflects pre-commit's exit code as the job
status is `pull_request`-only — the run exists solely to populate the
default-branch cache scope so PR branches can restore hook envs.

It could still fail on an *infrastructure* step, and did. A transient

    curl: (35) Recv failure: Connection reset by peer

while downloading the go-pre-commit release archive failed the install step
and turned an otherwise-green k5s main red (run 30964880559) — test and
build both passed, nothing was wrong with the repo or its hooks, and a
plain re-run went green with no change. Because callers pin `@main`, that
failure mode was reachable from every service repo's default branch.

A seed run that fails costs PRs a cold cache, not correctness. That is not
worth a red ❌ on a service repo's default branch, so the job is now
`continue-on-error` on push.

PR runs are deliberately untouched: they keep failing loudly, because that
❌ is what makes the sticky advisory comment worth reading.

The root cause is fixed separately in the action itself (blairham/go-pre-commit#33,
released as v4.6.1 — `curl --retry` only covers transient HTTP responses and
timeouts, never transport errors like a mid-transfer reset). This is the
defense-in-depth half: even with retries, an infra step failing on a seed run
should not gate anything. Bumping the pinned action version to v4.6.1 is a
separate change.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant