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 {
breakView on GitHub (pinned to 4000b2338a)
Solutions
- 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.
- If it's 403 from GitHub, wait for the rate-limit window or authenticate (GITHUB_TOKEN) and retry.
- Retry the update later if the status is 5xx — it is usually a transient server/CDN problem.
- 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.
- 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
- Ping the release URL with curl -I before running self-update
- Pin to a 'latest' asset URL that the release pipeline keeps valid
- Authenticate GitHub requests to avoid 403 rate limits
- Check github.com rate-limit headers when updating from CI
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
- range chunk retries exhausted
- request usage endpoint: %w
- reasonix: POST %s: %w
- init failed: %w
- begin failed: %w
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/e9b753457e085f33.
Report an issue: GitHub.