{"record":{"id":"b3463a6121d2838e","repo":"ipfs/kubo","slug":"github-api-returned-http-d-for-s","errorCode":null,"errorMessage":"GitHub API returned HTTP %d for %s","messagePattern":"GitHub API returned HTTP (.+?) for (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/commands/update_github.go","lineNumber":102,"sourceCode":"\t}\n\n\tresp, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif resp.StatusCode == http.StatusForbidden || resp.StatusCode == http.StatusTooManyRequests {\n\t\tresp.Body.Close()\n\t\thint := \"\"\n\t\tif githubToken() == \"\" {\n\t\t\thint = \" (hint: set GITHUB_TOKEN or GH_TOKEN to avoid rate limits)\"\n\t\t}\n\t\treturn nil, fmt.Errorf(\"GitHub API rate limit exceeded%s\", hint)\n\t}\n\n\tif resp.StatusCode != http.StatusOK {\n\t\tresp.Body.Close()\n\t\treturn nil, fmt.Errorf(\"GitHub API returned HTTP %d for %s\", resp.StatusCode, url)\n\t}\n\n\treturn resp, nil\n}\n\nfunc githubToken() string {\n\tif t := os.Getenv(\"GITHUB_TOKEN\"); t != \"\" {\n\t\treturn t\n\t}\n\treturn os.Getenv(\"GH_TOKEN\")\n}\n\n// githubLatestRelease returns the newest release that has a platform asset\n// for the current GOOS/GOARCH. This avoids false positives when a release\n// tag exists but artifacts haven't been uploaded yet.\nfunc githubLatestRelease(ctx context.Context, includePre bool) (*ghRelease, error) {\n\treleases, err := githubListReleases(ctx, 10, includePre)\n\tif err != nil {","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/ipfs/kubo/blob/329838acdfafae224582930457efe80aa217afc0/core/commands/update_github.go#L84-L120","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nresp, err := githubGet(ctx, \"https://api.github.com/repos/ipfs/kubo/releases/tags/\"+tag) // tag=\"v9.9.9\" -> 404\n// after\ntag, err := githubLatestTag(ctx) // discover a valid tag first\nif err != nil { return err }\nresp, err := githubGet(ctx, \"https://api.github.com/repos/ipfs/kubo/releases/tags/\"+tag)","handlingStrategy":"try-catch","validationCode":"// verify tag exists before fetching its release\ntags, _, err := ghClient.Repositories.ListTags(ctx, \"ipfs\", \"kubo\", nil)\nif err != nil || !slices.ContainsFunc(tags, func(t *github.RepositoryTag) bool { return t.GetName() == tag }) {\n\treturn fmt.Errorf(\"tag %q not found in ipfs/kubo\", tag)\n}","typeGuard":null,"tryCatchPattern":"resp, err := githubGet(ctx, url)\nif err != nil {\n\tvar httpErr string\n\tif strings.Contains(err.Error(), \"GitHub API returned HTTP \") {\n\t\t_, code, _ := strings.Cut(err.Error(), \"HTTP \")\n\t\tswitch code[:3] {\n\t\tcase \"404\": return fmt.Errorf(\"release/tag not found\")\n\t\tcase \"401\": return fmt.Errorf(\"invalid GitHub token\")\n\t\tdefault: return fmt.Errorf(\"github outage or proxy error, retry later: %w\", err)\n\t\t}\n\t}\n\treturn err\n}","preventionTips":["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"],"tags":["github","http","network","api-error","cli"],"backgroundTag":"http-4xx-upstream-error","analyzedSha":"329838acdfafae224582930457efe80aa217afc0","analyzedAt":"2026-09-03T18:30:52.135Z","contentChangedAt":"2026-09-03T18:30:52.135Z","schemaVersion":2},"datasetVersion":"2026-09-11T00:17:11.886Z"}