{"record":{"id":"6500171c74f35666","repo":"GoogleContainerTools/skaffold","slug":"http-d-error-q","errorCode":null,"errorMessage":"http %d, error %q","messagePattern":"http (.+?), error %q","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/skaffold/util/http.go","lineNumber":40,"sourceCode":"\t\"net/http\"\n\n\t\"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/version\"\n)\n\nfunc Download(url string) ([]byte, error) {\n\tclient := http.Client{}\n\treq, err := http.NewRequest(\"GET\", url, nil)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"creating http request: %w\", err)\n\t}\n\treq.Header.Set(\"User-Agent\", version.UserAgentWithClient())\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn nil, fmt.Errorf(\"http %d, error %q\", resp.StatusCode, resp.Status)\n\t}\n\treturn io.ReadAll(resp.Body)\n}\n","sourceCodeStart":22,"sourceCodeEnd":44,"githubUrl":"https://github.com/GoogleContainerTools/skaffold/blob/a1189de023efc32d4b8e11f395acc678aa555011/pkg/skaffold/util/http.go#L22-L44","documentation":"Download requires an HTTP 200 response; any other status code produces this error with the numeric code and the status text (e.g. 'http 404, error \"404 Not Found\"'). It is a guard against treating error pages or redirects-to-error bodies as valid payloads.","triggerScenarios":"client.Do succeeds but resp.StatusCode != 200: 404 (file removed/moved on GCS), 403 (permissions/blocked by firewall), 429 (rate limited), 5xx (server error).","commonSituations":"Fetching a remote skaffold config or latest-version file whose path changed; GCS bucket made private; corporate proxies returning 403; rate limiting after many checks; typos in remote config URLs in skaffold.yaml.","solutions":["Check the status code in the message: 404 means wrong/removed URL; 403 means access denied; 429 means back off and retry.","Verify the URL is still valid by curling it and comparing status.","For GCS, confirm the object exists and the bucket is publicly readable (or use authenticated access).","Add retry with backoff for transient 429/5xx before treating it as fatal.","If a proxy interferes, allowlist the host or fix proxy credentials."],"exampleFix":"// before: one-shot download, fails hard on 429\nb, err := util.Download(remoteCfgURL)\n// after: retry transient statuses\nvar b []byte\nfor i := 0; i < 3; i++ {\n    b, err = util.Download(remoteCfgURL)\n    if err == nil || !strings.Contains(fmt.Sprint(err), \"http 4\") || !strings.Contains(fmt.Sprint(err), \"429\") {\n        break\n    }\n    time.Sleep(time.Duration(1<<i) * time.Second)\n}","handlingStrategy":"retry","validationCode":"// can't pre-validate server status, but can pre-check reachability\nresp, err := http.Head(url)\nif err == nil && resp.StatusCode >= 400 {\n    return fmt.Errorf(\"URL returns %d before download\", resp.StatusCode)\n}","typeGuard":"func isHTTPStatusError(err error) bool { return strings.Contains(err.Error(), \"http \") && strings.Contains(err.Error(), \", error \") }\n\nfunc statusCodeFrom(err error) int {\n    var code int\n    fmt.Sscanf(err.Error(), \"http %d\", &code)\n    return code\n}","tryCatchPattern":"b, err := util.Download(url)\nif err != nil {\n    if code := statusCodeFrom(err); code == 429 || code >= 500 {\n        // retry with exponential backoff\n    } else if code == 404 {\n        return fmt.Errorf(\"resource not found at %s — check the URL\", url)\n    }\n    return err\n}","preventionTips":["Verify the URL returns 200 with curl or a HEAD pre-check before relying on it","Retry 429/5xx with exponential backoff; fail fast on 4xx client errors","Confirm GCS object existence and public-read ACL for public downloads","Keep URLs to remote configs in version control and validate them in CI"],"tags":["http","network","status-code","gcs"],"backgroundTag":"unexpected-http-status","analyzedSha":"a1189de023efc32d4b8e11f395acc678aa555011","analyzedAt":"2026-09-05T12:09:27.064Z","contentChangedAt":"2026-09-05T12:09:27.064Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}