chenhg5/cc-connect · error

HTTP %d for %s

Error message

HTTP %d for %s

What it means

downloadFile in the self-updater fails closed on any HTTP status other than 200 OK: it reads the body only after this check, so a non-OK response yields this wrapped error carrying the status code and the URL instead of update bytes. It exists so callers see the real status (e.g. 404, 403, 503) rather than a confusing 'unexpected end of JSON' or empty-archive error downstream.

Source

Thrown at core/updater.go:195

				return fmt.Errorf("too many redirects")
			}
			return nil
		},
	}
	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		return nil, err
	}
	req.Header.Set("User-Agent", "cc-connect-updater")

	resp, err := client.Do(req)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("HTTP %d for %s", resp.StatusCode, url)
	}

	return io.ReadAll(resp.Body)
}

func extractBinaryFromTarGz(data []byte) ([]byte, error) {
	r := bytes.NewReader(data)
	gr, err := gzip.NewReader(r)
	if err != nil {
		return nil, err
	}
	defer gr.Close()

	tr := tar.NewReader(gr)
	for {
		hdr, err := tr.Next()
		if err == io.EOF {
			break

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Check the status code in the error and fetch the URL with curl -I to see the actual response; fix the download URL or asset name it points to.
  2. If it's 403 from GitHub, wait for the rate-limit window or authenticate (GITHUB_TOKEN) and retry.
  3. Retry the update later if the status is 5xx — it is usually a transient server/CDN problem.
  4. Verify the release exists for your platform (asset names differ per OS/arch) and upgrade in two steps if the current version points to a dead URL.
  5. As a last resort, download and replace the binary manually using the same layout the updater expects (tar.gz or zip containing a cc-connect* file).

Example fix

// before
resp, err := http.Get(url) // url points to v0.9 asset that was replaced
...
// HTTP 404 for https://.../cc-connect-v0.9-linux-amd64.tar.gz
// after
# fix the asset URL for the new release
resp, err := http.Get("https://github.com/org/cc-connect/releases/latest/download/cc-connect-linux-amd64.tar.gz")
Defensive patterns

Strategy: retry

Validate before calling

resp, err := http.Head(url)
if err != nil || resp.StatusCode != http.StatusOK {
    return fmt.Errorf("download URL not ready: status=%v err=%v", resp.StatusCode, err)
}

Try / catch

if err := selfUpdate(); err != nil {
    var he *StatusError
    if errors.As(err, &he) && he.Code >= 500 {
        // transient: retry with backoff
    } else if errors.As(err, &he) && he.Code == 403 {
        // rate limited: wait for Reset-After
    }
}

Prevention

When it happens

Trigger: SelfUpdate -> downloadFile fetched the release asset URL and the server responded with any status != 200: release asset renamed or deleted, tag missing, download URL typo, GitHub rate limiting/502, proxy returning an error page, private repo asset without a token.

Common situations: Running an old version whose hardcoded download URL no longer resolves (404); corporate proxy intercepting the download with a 403 page; GitHub API rate limit for unauthenticated requests (403 with rate-limit headers); transient CDN errors (502/503); mirroring the binary under a changed asset naming scheme.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06). Data as JSON: /api/errors/e9b753457e085f33. Report an issue: GitHub.