GuidesRunning & maintaining

“could not read Username for 'https://github.com'” on a public repo: why a cloud server gets asked for credentials

GitHub answers some anonymous protocol-v2 fetches over HTTP/2 from datacenter ranges with a 401, and git turns it into a username prompt plus “expected flush after ref listing”. The trace, the one-line fix, and what breaks downstream.

September 5, 2026The Everpod team
The short answer

Your git is fine and the repository really is public. From some cloud address ranges, GitHub answers the second half of an anonymous clone (the git-upload-pack POST, over HTTP/2 with git’s protocol version 2) with an HTTP 401 asking for Basic credentials. Git reads a 401 as “this needs a username,” tries to prompt for one, and with no terminal to ask it dies with “could not read Username for 'https://github.com'”, followed by expected flush after ref listing because the exchange was cut off mid-protocol. It reproduced on three Hetzner servers in two locations on September 3, 2026, while a laptop cloned the same repository normally. Two one-line fixes work from the server:

git -c http.version=HTTP/1.1 clone https://github.com/octocat/Hello-World
git -c protocol.version=0  clone https://github.com/octocat/Hello-World

What the trace shows

Run the clone with curl tracing and the shape is unmistakable:

GIT_TRACE_CURL=1 git clone https://github.com/octocat/Hello-World 2>&1 | grep -E "^(> (GET|POST)|< HTTP|< www-auth)"

The first request, the ref advertisement (a GET of info/refs for the upload-pack service, sent with Git-Protocol: version=2), comes back 200 from GitHub’s front end. The second, the POST to git-upload-pack that actually negotiates what to fetch, comes back HTTP/2 401 with a www-authenticate header demanding Basic realm="GitHub". GitHub is demanding credentials for an anonymous fetch of a public repository, halfway through the conversation. Git has no credentials to offer, tries to ask you for some, and in a non-interactive context (an agent’s shell, a container, CI with GIT_TERMINAL_PROMPT=0) that attempt is the first error. The second is git noticing that the protocol-v2 exchange never reached its end.

Everything else we checked from the same server was healthy: a plain curl to both endpoints returned 200, GitLab cloned normally over HTTPS, SSH to github.com:22 worked and a deploy key fetched a private repository without complaint. The rule applies to one specific combination: anonymous, protocol v2, HTTP/2, and the address range the request comes from. Change any of the first three and it passes; hence both fixes.

Why a server and not your laptop

Because the deciding input is the address. The same command from a laptop (git 2.33 on Windows, over a VPN) fetched the same repository at the same minute. From the server’s host, from a container on it, and from a second server in another Hetzner location (git 2.43 on Ubuntu), it failed identically, and it was still failing an hour later. That is an edge rule on GitHub’s side keyed on where the request originates, not a broken client and not a rate limit you triggered. We cannot see the rule itself and GitHub does not document it, so treat the mechanism as observed rather than explained. The same error pair shows up sporadically for public repositories in GitHub Actions too (actions/checkout issue #2351, opened December 2025, reported at under one percent of runs), which fits a network-position rule better than a client bug.

The fixes, from smallest to permanent

# once, for this command
git -c http.version=HTTP/1.1 clone https://github.com/OWNER/REPO

# for one user on the machine
git config --global http.version HTTP/1.1

# for every user on the machine (what an image or a server build should do)
sudo git config --system http.version HTTP/1.1

protocol.version=0 works too, by falling back to git’s older wire protocol; forcing HTTP/1.1 is the smaller change and keeps protocol v2’s efficiency. For git the difference between HTTP/1.1 and HTTP/2 is negligible. If the machine exists to run an agent, put the line in /etc/gitconfig at build time so every tool on it inherits the fix without knowing the story.

What else breaks, and what does not

Anything that shells out to git over HTTPS inherits the failure: pip install git+https://… pointed at GitHub, and any build step that clones a dependency. npm is mostly unaffected, because for github:owner/repo specs it fetches a tarball rather than running git. SSH is unaffected entirely, which is one more reason the deploy-key pattern is the right way to give an agent a private repository. And with the config line in place, all three of git clone, pip install git+https and npm install github: worked from the same server the same afternoon.

The agent angle

An agent that hits this error will draw the reasonable wrong conclusion: GitHub wants credentials, so it will ask you for a token and try to embed it in the URL. That is the reflex to head off. The repository is public, no credential is owed, and a token pasted into a chat to fix a network quirk is a secret spent for nothing. Set the config once on the machine, tell the agent in its notes that public clones over HTTPS need no login there, and re-run the trace above the next time something similar appears: GitHub’s edge rules move, and a fix that was needed in September may be a harmless no-op by the time you read this.

Your own cloud agent, set up for you.

Everpod runs OpenClaw on a private, always-on computer of its own: set up, secured and backed up, with model usage included. You name your agent, and say hello about fifteen minutes later.

Create your agent

First month half price, then $29/mo · model usage included · cancel anytime

Wondering what you’d do with one? See what a cloud agent can do