Angular CI: WASM bundle download flakes on HTTP/2 stream reset (curl exit 92) #816

Closed
opened 2026-07-23 15:19:38 +00:00 by spikerj · 1 comment
Owner

Symptom

spikersoft-angular build job fails in Download SpikerSoft.Wasm Roslyn bundle from Gitea (run 17752):

Fetching SpikerSoft.Wasm bundle: version=latest
...
 11 44.7M   11 5120k    0     0  13.5M      0 ...
curl: (92) HTTP/2 stream 1 was not closed cleanly: INTERNAL_ERROR (err 2)
Error: Process completed with exit code 92.

Root cause

Transfer-layer flake, not a missing package — the download authenticated and streamed ~5 MB of the 44.7 MB tarball before the server/proxy reset the HTTP/2 stream. The latest generic package exists and is pullable.

This is the same Gitea HTTP/2 flakiness the workflow's git steps already work around with git config --global http.version HTTP/1.1 (lines 120/326/484 of main.yml). The curl bundle download never got the equivalent treatment, so a large body over HTTP/2 occasionally trips INTERNAL_ERROR.

Fix

Pin the download to HTTP/1.1 and add retries:

curl --fail --user spikerj:$RUNNER_TOKEN -L \
    --http1.1 \
    --retry 5 --retry-delay 3 --retry-all-errors \
    -o wasm-bundle.tar.gz \
    "$BASE/$VERSION/spikersoft-wasm-bundle.tar.gz"

--http1.1 removes the HTTP/2 stream-reset root cause; --retry-all-errors covers any residual transient blip (a partial -o file is truncated, so a retry re-fetches cleanly).

## Symptom `spikersoft-angular` build job fails in **Download SpikerSoft.Wasm Roslyn bundle from Gitea** (run [17752](https://git.spikersoft.com/spikerj/spikersoft-angular/actions/runs/17752/jobs/68543)): ``` Fetching SpikerSoft.Wasm bundle: version=latest ... 11 44.7M 11 5120k 0 0 13.5M 0 ... curl: (92) HTTP/2 stream 1 was not closed cleanly: INTERNAL_ERROR (err 2) Error: Process completed with exit code 92. ``` ## Root cause Transfer-layer flake, **not** a missing package — the download authenticated and streamed ~5 MB of the 44.7 MB tarball before the server/proxy reset the HTTP/2 stream. The `latest` generic package exists and is pullable. This is the same Gitea HTTP/2 flakiness the workflow's **git** steps already work around with `git config --global http.version HTTP/1.1` (lines 120/326/484 of `main.yml`). The `curl` bundle download never got the equivalent treatment, so a large body over HTTP/2 occasionally trips `INTERNAL_ERROR`. ## Fix Pin the download to HTTP/1.1 and add retries: ```bash curl --fail --user spikerj:$RUNNER_TOKEN -L \ --http1.1 \ --retry 5 --retry-delay 3 --retry-all-errors \ -o wasm-bundle.tar.gz \ "$BASE/$VERSION/spikersoft-wasm-bundle.tar.gz" ``` `--http1.1` removes the HTTP/2 stream-reset root cause; `--retry-all-errors` covers any residual transient blip (a partial `-o` file is truncated, so a retry re-fetches cleanly).
Author
Owner

Fixed and verified. spikersoft-angular commit 489f16ca — "ci: pin WASM bundle download to HTTP/1.1 with retries (#816)" — is on master.

The download step now carries exactly the prescribed treatment, with the reasoning captured inline:

curl --fail --user spikerj:${{ env.RUNNER_TOKEN }} -L \
    --http1.1 \
    --retry 5 --retry-delay 3 --retry-all-errors \
    -o wasm-bundle.tar.gz \
    "$BASE/$VERSION/spikersoft-wasm-bundle.tar.gz"

Verified on master today: the build job (which owns this step) has succeeded on every master run, including the several runs merged this evening — no recurrence of curl exit 92. Closing.

— Opus 5 Agent

Fixed and verified. spikersoft-angular commit `489f16ca` — "ci: pin WASM bundle download to HTTP/1.1 with retries (#816)" — is on master. The download step now carries exactly the prescribed treatment, with the reasoning captured inline: ``` curl --fail --user spikerj:${{ env.RUNNER_TOKEN }} -L \ --http1.1 \ --retry 5 --retry-delay 3 --retry-all-errors \ -o wasm-bundle.tar.gz \ "$BASE/$VERSION/spikersoft-wasm-bundle.tar.gz" ``` Verified on master today: the `build` job (which owns this step) has succeeded on every master run, including the several runs merged this evening — no recurrence of curl exit 92. Closing. — Opus 5 Agent
Sign in to join this conversation.