ipfs/kubo · error
download returned HTTP %d
Error message
download returned HTTP %d
What it means
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.
Source
Thrown at core/commands/update_github.go:225
}
// downloadAsset downloads a release asset by its browser_download_url.
// This hits GitHub's CDN directly, not the API, so no auth headers are needed.
func downloadAsset(ctx context.Context, url string) ([]byte, error) {
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
if err != nil {
return nil, err
}
req.Header.Set("User-Agent", "kubo/"+version.CurrentVersionNumber)
resp, err := http.DefaultClient.Do(req)
if err != nil {
return nil, fmt.Errorf("downloading asset: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("download returned HTTP %d", resp.StatusCode)
}
data, err := io.ReadAll(io.LimitReader(resp.Body, maxDownloadSize+1))
if err != nil {
return nil, fmt.Errorf("reading download: %w", err)
}
if int64(len(data)) > maxDownloadSize {
return nil, fmt.Errorf("download exceeds maximum size of %d bytes", maxDownloadSize)
}
return data, nil
}
// downloadAndVerifySHA512 downloads the .sha512 sidecar file for the given
// archive URL and verifies the archive data against it.
func downloadAndVerifySHA512(ctx context.Context, data []byte, archiveURL string) error {
sha512URL := archiveURL + ".sha512"
checksumData, err := downloadAsset(ctx, sha512URL)
if err != nil {View on GitHub (pinned to 329838acdf)
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
Defensive patterns
Strategy: retry
Validate before calling
// before calling the updater, check reachability of the asset URL
resp, err := http.Head(assetURL)
if err != nil {
return fmt.Errorf("cannot reach github.com: %w", err)
}
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("asset unavailable, HTTP %d — retry later", resp.StatusCode)
} Try / catch
// CLI errors surface as the command's error output, not panics
if err := cmd.Run(); err != nil {
if strings.Contains(err.Error(), "download returned HTTP") {
// transient GitHub CDN issue: wait and retry with backoff
time.Sleep(retryDelay)
return cmd.Run()
}
return err
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- GitHub API returned HTTP %d for %s
- downloading checksum file: %w
- GitHub API rate limit exceeded%s
- reading download: %w
- download exceeds maximum size of %d bytes
AI-assisted analysis of ipfs/kubo@329838acdf (2026-09-03).
Data as JSON: /api/errors/93ada949bd195cbc.
Report an issue: GitHub.