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

  1. Wait a few hours and retry if the release is brand new (artifacts may still be uploading)
  2. Check the asset exists at the URL in a browser (404 means the asset name/tag changed)
  3. Retry later on 429/5xx — GitHub CDN rate limits are temporary
  4. Check for a proxy/firewall intercepting HTTPS to github.com and use a direct connection
  5. 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

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


AI-assisted analysis of ipfs/kubo@329838acdf (2026-09-03). Data as JSON: /api/errors/93ada949bd195cbc. Report an issue: GitHub.