jeessy2/ddns-go · error

could not download release from %s. Response code: %d

Error message

could not download release from %s. Response code: %d

What it means

The HTTP-status branch of downloadAssetFromURL: after a successful client.Get, any status code >= 300 causes the body to be closed and this error returned with the URL and code. Unlike error 81, the server responded but refused the download (redirect not followed, 403/404 rate limit, 5xx, etc.).

Source

Thrown at util/update/package.go:72

// cmdPath 是命令可执行文件的文件路径。
func to(assetURL, assetFileName, cmdPath string) error {
	src, err := downloadAssetFromURL(assetURL)
	if err != nil {
		return err
	}
	defer src.Close()
	return decompressAndUpdate(src, assetFileName, cmdPath)
}

func downloadAssetFromURL(url string) (rc io.ReadCloser, err error) {
	client := util.CreateHTTPClient()
	resp, err := client.Get(url)
	if err != nil {
		return nil, fmt.Errorf("could not download release from %s: %v", url, err)
	}
	if resp.StatusCode >= 300 {
		resp.Body.Close()
		return nil, fmt.Errorf("could not download release from %s. Response code: %d", url, resp.StatusCode)
	}

	return resp.Body, nil
}

View on GitHub (pinned to 5874c2e666)

Solutions

  1. Open the URL in a browser or curl -I to confirm the status code and whether the asset still exists.
  2. Update the release/asset URL to the current published location (404/403 case).
  3. Authenticate or wait out the rate limit if the code is 403/429 from GitHub.
  4. Handle 5xx with retry/backoff; check resp.StatusCode explicitly in the caller to give user-facing messages.

Example fix

// before
rc, err := to(assetURL)
if err != nil { return err }
// after
rc, err := to(assetURL)
if err != nil {
	if strings.Contains(err.Error(), "Response code: 404") {
		return fmt.Errorf("asset %s no longer exists; please check the release page", assetURL)
	}
	return err
}
Defensive patterns

Strategy: validation

Validate before calling

// HEAD check before full download
resp, err := http.Head(assetURL)
if err != nil {
	return err
}
if resp.StatusCode >= 300 {
	return fmt.Errorf("asset %s returned %d; check the release page", assetURL, resp.StatusCode)
}

Try / catch

rc, err := to(assetURL)
if err != nil {
	var statusErr *StatusError // if you introduce a typed error
	if errors.As(err, &statusErr) && statusErr.Code == 404 {
		return fmt.Errorf("release asset removed; pick another version")
	}
	return err
}

Prevention

When it happens

Trigger: client.Get(url) succeeded but resp.StatusCode >= 300 — e.g. 404 for a removed release asset, 403 rate-limit or private repo, 302 when redirects are disabled, 500 server error. Raised in downloadAssetFromURL, propagated to to().

Common situations: Fetching a deleted/renamed GitHub release asset; hitting GitHub API rate limits (403 with X-RateLimit-Remaining: 0); asset URL pointing at a moved release; server maintenance 5xx.

Related errors


AI-assisted analysis of jeessy2/ddns-go@5874c2e666 (2026-09-03). Data as JSON: /api/errors/a0de4419575407ba. Report an issue: GitHub.