ipfs/kubo · error
GitHub API returned HTTP %d for %s
Error message
GitHub API returned HTTP %d for %s
What it means
githubGet returns `GitHub API returned HTTP %d for %s` for any non-200 response from the GitHub API that is not the rate-limit 403/429 case, including the URL that failed. It is a generic upstream HTTP failure wrapper so the developer can see the status code and endpoint.
Source
Thrown at core/commands/update_github.go:102
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
return nil, err
}
if resp.StatusCode == http.StatusForbidden || resp.StatusCode == http.StatusTooManyRequests {
resp.Body.Close()
hint := ""
if githubToken() == "" {
hint = " (hint: set GITHUB_TOKEN or GH_TOKEN to avoid rate limits)"
}
return nil, fmt.Errorf("GitHub API rate limit exceeded%s", hint)
}
if resp.StatusCode != http.StatusOK {
resp.Body.Close()
return nil, fmt.Errorf("GitHub API returned HTTP %d for %s", resp.StatusCode, url)
}
return resp, nil
}
func githubToken() string {
if t := os.Getenv("GITHUB_TOKEN"); t != "" {
return t
}
return os.Getenv("GH_TOKEN")
}
// githubLatestRelease returns the newest release that has a platform asset
// for the current GOOS/GOARCH. This avoids false positives when a release
// tag exists but artifacts haven't been uploaded yet.
func githubLatestRelease(ctx context.Context, includePre bool) (*ghRelease, error) {
releases, err := githubListReleases(ctx, 10, includePre)
if err != nil {View on GitHub (pinned to 329838acdf)
Solutions
- Read the status code in the message: 404 means the tag/release URL is wrong — verify the tag exists (`gh release view <tag>` or the releases page).
- 401: refresh/replace an invalid GITHUB_TOKEN; unset it entirely if you intended anonymous access.
- 5xx: check https://www.githubstatus.com and retry with backoff after the outage.
- If behind a corporate proxy, fix proxy env vars (HTTPS_PROXY) so api.github.com is reachable, and retry.
Example fix
// before
resp, err := githubGet(ctx, "https://api.github.com/repos/ipfs/kubo/releases/tags/"+tag) // tag="v9.9.9" -> 404
// after
tag, err := githubLatestTag(ctx) // discover a valid tag first
if err != nil { return err }
resp, err := githubGet(ctx, "https://api.github.com/repos/ipfs/kubo/releases/tags/"+tag) Defensive patterns
Strategy: try-catch
Validate before calling
// verify tag exists before fetching its release
tags, _, err := ghClient.Repositories.ListTags(ctx, "ipfs", "kubo", nil)
if err != nil || !slices.ContainsFunc(tags, func(t *github.RepositoryTag) bool { return t.GetName() == tag }) {
return fmt.Errorf("tag %q not found in ipfs/kubo", tag)
} Try / catch
resp, err := githubGet(ctx, url)
if err != nil {
var httpErr string
if strings.Contains(err.Error(), "GitHub API returned HTTP ") {
_, code, _ := strings.Cut(err.Error(), "HTTP ")
switch code[:3] {
case "404": return fmt.Errorf("release/tag not found")
case "401": return fmt.Errorf("invalid GitHub token")
default: return fmt.Errorf("github outage or proxy error, retry later: %w", err)
}
}
return err
} Prevention
- Validate release tags against the repo before fetching
- Check https://www.githubstatus.com when seeing 5xx
- Keep GITHUB_TOKEN valid and unexpired
- Verify proxy/HTTPS_PROXY settings when behind a corporate firewall
When it happens
Trigger: githubListReleases or githubReleaseByTag hitting api.github.com and receiving 404 (bad tag/org/repo), 401 (invalid/expired token), 5xx (GitHub outage), or any other unexpected status like 410.
Common situations: Requesting a release tag that was deleted or renamed, an expired/revoked GITHUB_TOKEN, a typo'd repo/tag in code or tests, GitHub incident downtime, or an intercepting corporate proxy returning error pages.
Related errors
- GitHub API rate limit exceeded%s
- download returned HTTP %d
- 'ipfs id' cannot query information on remote peers without a
- no release found with a binary for %s/%s
- downloading checksum file: %w
AI-assisted analysis of ipfs/kubo@329838acdf (2026-09-03).
Data as JSON: /api/errors/b3463a6121d2838e.
Report an issue: GitHub.