Skip to content

ci: keep the runner image's git off HTTP/2 so dependency clones stop failing - #401

Merged
Yaraslaut merged 1 commit into
masterfrom
ci/runner-http1-clone-fix
Sep 2, 2026
Merged

ci: keep the runner image's git off HTTP/2 so dependency clones stop failing#401
Yaraslaut merged 1 commit into
masterfrom
ci/runner-http1-clone-fix

Conversation

@Yaraslaut

Copy link
Copy Markdown
Member

The failure

Six self-hosted jobs on run 33627249007 (clang-release, clang-tsan, both all optional features legs, both Application ladder legs) failed in Configure, 17 occurrences of:

fatal: could not read Username for 'https://github.com': No such device or address
fatal: expected flush after ref listing
Had to git clone more than once: 3 times.
CMake Error ... Failed to clone repository: 'https://github.com/stephenberry/glaze.git'

That is CMakeLists.txt:151's FetchContent fallback for glaze — the only anonymous clone in the build.

Root cause

It looks like a credentials or rate-limit problem and is neither. Reproduced live from a running runner container: GitHub answers the info/refs GET with 200, then answers the git-upload-pack POST on the same reused HTTP/2 connection with a spurious 401 + www-authenticate: Basic realm="GitHub", which git turns into the username prompt.

Client Result
Runner container, default (HTTP/2) 3 of 10 ls-remotes succeed
Runner container, -c http.version=HTTP/1.1 10 of 10
Runner container, -c protocol.version=0 10 of 10
Docker host, same public IP (libcurl 8.21) 10 of 10
Container with git 2.55 from ppa:git-core/ppa 2 of 10 — unchanged

So it is not the network, not the IP, not GitHub throttling (anonymous API rate limit read 60/60 remaining), and not git's version — it is Ubuntu 24.04's libcurl 8.5.0 / nghttp2 1.59, which 24.04 has no newer replacement for. Only authenticated requests escape the 401, because git retries them with credentials — which is why actions/checkout always worked here and only the dependency clone broke, and why GitHub-hosted runs never showed it.

The change

  • Dockerfile: RUN git config --system http.version HTTP/1.1, system-wide because the bug is in the HTTP stack rather than in anything specific to that remote.
  • README.md: new Dependency clones and HTTP/2 section with the symptom, the evidence, and the in-place fix for containers built from an older image (docker exec -u root <name> git config --system http.version HTTP/1.1).
  • README.md: host inventory removed — it listed three hosts, two of which no longer exist, and would drift again. Settings → Actions → Runners and gh api repos/LASTRADA-Software/morph/actions/runners are the live answer. Sizing and fastcached recipes stay, reworded as per-platform guidance rather than claims about particular machines.

Verification

The in-place config was applied to all five online runners, each then verified at 10 of 10 clones (from 3 of 10). Rerunning the six failed jobs on #395 carried them past Configure, where they had previously died in 27–44 s.

🤖 Generated with Claude Code

https://claude.ai/code/session_01EZCZ8SoqHKrcmXxwb7q22D

…failing

Six self-hosted jobs on run 33627249007 (clang-release, clang-tsan, both
all-optional-features legs, both Application ladder legs) died in
Configure with 17 occurrences of

  fatal: could not read Username for 'https://github.com': No such device or address
  fatal: expected flush after ref listing
  Had to git clone more than once: 3 times.
  CMake Error ... Failed to clone repository: 'https://github.com/stephenberry/glaze.git'

That is CMakeLists.txt:151's FetchContent fallback for glaze, the only
anonymous clone the build makes. It reads as a credentials or rate-limit
problem and is neither.

Reproduced from a running runner container: GitHub answers the info/refs
GET with 200 and then answers the git-upload-pack POST on the same reused
HTTP/2 connection with a spurious 401 and `www-authenticate: Basic
realm="GitHub"`, which git turns into the username prompt above. Measured
7 failures in 10 ls-remotes; with -c http.version=HTTP/1.1 or
-c protocol.version=0, 10 in 10 succeed.

It is the client stack, not the network, the IP, or GitHub throttling:
the same clone from the Docker host -- same public address -- is 10 in
10, and the anonymous API rate limit reads 60/60 remaining. It is not
git's version either: git 2.55 from ppa:git-core/ppa inside the image
fails at the same rate as the distro's 2.43, because both link Ubuntu
24.04's libcurl 8.5.0 / nghttp2 1.59 (the host's is 8.21). 24.04 has no
newer libcurl to install, so the fix is to keep git off HTTP/2. Only
authenticated requests escape the 401 -- git retries those with
credentials -- which is why actions/checkout has always worked here and
only the dependency clone breaks, and why the GitHub-hosted path never
showed this.

Applied system-wide rather than per-repo because the bug is in the HTTP
stack, not in anything specific to that remote. Containers built from an
older image keep failing until recreated; the README records the in-place
`docker exec -u root ... git config --system http.version HTTP/1.1` for
that, which was run against the five online runners (each verified 10 in
10 afterwards) and turned the rerun of those six jobs past Configure.

The README's host inventory goes with it. It listed three hosts, two of
which no longer exist, and it will drift again -- Settings -> Actions ->
Runners and `gh api repos/LASTRADA-Software/morph/actions/runners` are
the live answer. The sizing and fastcached recipes stay, reworded as
per-platform guidance rather than claims about particular machines.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EZCZ8SoqHKrcmXxwb7q22D
@Yaraslaut
Yaraslaut merged commit a7a9998 into master Sep 2, 2026
19 checks passed
@codecov

codecov Bot commented Sep 2, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

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