{"record":{"id":"93ada949bd195cbc","repo":"ipfs/kubo","slug":"download-returned-http-d","errorCode":null,"errorMessage":"download returned HTTP %d","messagePattern":"download returned HTTP (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/commands/update_github.go","lineNumber":225,"sourceCode":"}\n\n// downloadAsset downloads a release asset by its browser_download_url.\n// This hits GitHub's CDN directly, not the API, so no auth headers are needed.\nfunc downloadAsset(ctx context.Context, url string) ([]byte, error) {\n\treq, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treq.Header.Set(\"User-Agent\", \"kubo/\"+version.CurrentVersionNumber)\n\n\tresp, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"downloading asset: %w\", err)\n\t}\n\tdefer resp.Body.Close()\n\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn nil, fmt.Errorf(\"download returned HTTP %d\", resp.StatusCode)\n\t}\n\n\tdata, err := io.ReadAll(io.LimitReader(resp.Body, maxDownloadSize+1))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"reading download: %w\", err)\n\t}\n\tif int64(len(data)) > maxDownloadSize {\n\t\treturn nil, fmt.Errorf(\"download exceeds maximum size of %d bytes\", maxDownloadSize)\n\t}\n\treturn data, nil\n}\n\n// downloadAndVerifySHA512 downloads the .sha512 sidecar file for the given\n// archive URL and verifies the archive data against it.\nfunc downloadAndVerifySHA512(ctx context.Context, data []byte, archiveURL string) error {\n\tsha512URL := archiveURL + \".sha512\"\n\tchecksumData, err := downloadAsset(ctx, sha512URL)\n\tif err != nil {","sourceCodeStart":207,"sourceCodeEnd":243,"githubUrl":"https://github.com/ipfs/kubo/blob/329838acdfafae224582930457efe80aa217afc0/core/commands/update_github.go#L207-L243","documentation":"downloadAsset fetches a GitHub release asset via its browser_download_url (GitHub CDN, no auth) and requires an exact HTTP 200. Any other status code (404, 403, 429, 5xx) makes it abort with this error before reading the body.","triggerScenarios":"The GET of a release asset URL returns a non-200 status: the asset was removed or renamed, the release tag is wrong, GitHub rate-limits or blocks the CDN request, a proxy intercepts the download, or the binary upload for a fresh release is not yet visible on the CDN.","commonSituations":"Running `ipfs update` right after a release is announced while CI artifacts are still propagating to GitHub's CDN; an interrupted/deleted release; corporate proxies returning 403/502 challenge pages; unauthenticated rate limiting (429) on shared CI IPs.","solutions":["Wait a few hours and retry if the release is brand new (artifacts may still be uploading)","Check the asset exists at the URL in a browser (404 means the asset name/tag changed)","Retry later on 429/5xx — GitHub CDN rate limits are temporary","Check for a proxy/firewall intercepting HTTPS to github.com and use a direct connection","Verify the release tag passed to the update command is a real, published release"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// before calling the updater, check reachability of the asset URL\nresp, err := http.Head(assetURL)\nif err != nil {\n\treturn fmt.Errorf(\"cannot reach github.com: %w\", err)\n}\nif resp.StatusCode != http.StatusOK {\n\treturn fmt.Errorf(\"asset unavailable, HTTP %d — retry later\", resp.StatusCode)\n}","typeGuard":null,"tryCatchPattern":"// CLI errors surface as the command's error output, not panics\nif err := cmd.Run(); err != nil {\n\tif strings.Contains(err.Error(), \"download returned HTTP\") {\n\t\t// transient GitHub CDN issue: wait and retry with backoff\n\t\ttime.Sleep(retryDelay)\n\t\treturn cmd.Run()\n\t}\n\treturn err\n}","preventionTips":["Do not run `ipfs update` in the minutes right after a release is announced; wait for artifacts to propagate","Check the release page in a browser to confirm the asset for your OS/arch exists first","Avoid unauthenticated high-frequency API/CDN access from shared CI IPs to dodge 429 rate limits","Ensure no transparent proxy intercepts HTTPS traffic to github.com"],"tags":["network","http","github","download"],"backgroundTag":"http-non-2xx-status","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"}