{"record":{"id":"c6097517fe85c4a6","repo":"GoogleContainerTools/skaffold","slug":"creating-http-request-w","errorCode":null,"errorMessage":"creating http request: %w","messagePattern":"creating http request: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/skaffold/util/http.go","lineNumber":31,"sourceCode":"See the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage util\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\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":13,"sourceCodeEnd":44,"githubUrl":"https://github.com/GoogleContainerTools/skaffold/blob/a1189de023efc32d4b8e11f395acc678aa555011/pkg/skaffold/util/http.go#L13-L44","documentation":"Download issues an HTTP GET via util.Download. This error means http.NewRequest failed to construct the request itself — almost always because the URL is malformed (no scheme, invalid characters, bad host). The URL parse error is wrapped.","triggerScenarios":"http.NewRequest(\"GET\", url, nil) errors: url passed to Download is empty, missing scheme ('storage.googleapis.com/...' without https://), contains spaces or invalid control characters, or is otherwise rejected by net/url parsing.","commonSituations":"Building URLs by string concatenation with unescaped user input (image names, ports, endpoints) e.g. in ReadConfiguration fetching remote configs; environment-provided endpoint strings with typos; URLs read from config with surrounding whitespace or quotes.","solutions":["Print/inspect the URL passed to Download; validate it has scheme://host format.","Trim whitespace/quotes from config-provided URLs before use (strings.TrimSpace).","Escape path segments with url.PathEscape when interpolating user data.","Reject empty URLs early with an explicit validation check."],"exampleFix":"// before\nurl := fmt.Sprintf(\"%s/%s\", base, name) // base may be \"example.com/x\" without scheme\nb, err := util.Download(url)\n// after\nu, err := nurl.Parse(strings.TrimSpace(base))\nif err != nil || u.Scheme == \"\" {\n    return nil, fmt.Errorf(\"invalid download URL: %q\", base)\n}\nb, err := util.Download(u.String())","handlingStrategy":"validation","validationCode":"u, err := url.Parse(rawURL)\nif err != nil {\n    return fmt.Errorf(\"invalid URL %q: %w\", rawURL, err)\n}\nif u.Scheme != \"http\" && u.Scheme != \"https\" || u.Host == \"\" {\n    return fmt.Errorf(\"URL must be absolute with host: %q\", rawURL)\n}","typeGuard":"func isDownloadableURL(s string) bool {\n    u, err := url.Parse(strings.TrimSpace(s))\n    return err == nil && (u.Scheme == \"http\" || u.Scheme == \"https\") && u.Host != \"\"\n}","tryCatchPattern":"b, err := util.Download(url)\nif err != nil && strings.Contains(err.Error(), \"creating http request\") {\n    return fmt.Errorf(\"malformed download URL %q: %w\", url, err)\n}","preventionTips":["Always construct URLs with url.Parse/url.PathEscape, never raw string concat of user input","Trim whitespace and quotes from URLs read from config or env","Assert scheme and host presence before downloading"],"tags":["http","url","network","validation"],"backgroundTag":"invalid-url","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"}