{"record":{"id":"f7701ff7e9f01961","repo":"hashicorp/terraform","slug":"registry-response-includes-invalid-download-url-m","errorCode":null,"errorMessage":"registry response includes invalid download URL: must use http or https scheme","messagePattern":"registry response includes invalid download URL: must use http or https scheme","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/getproviders/registry_client.go","lineNumber":289,"sourceCode":"\t\t\tif err != nil {\n\t\t\t\treturn PackageMeta{}, err\n\t\t\t}\n\t\t\tprotoErr.Suggestion = closest\n\t\t\treturn PackageMeta{}, protoErr\n\t\t}\n\t}\n\n\tif body.OS != target.OS || body.Arch != target.Arch {\n\t\treturn PackageMeta{}, fmt.Errorf(\"registry response to request for %s archive has incorrect target %s\", target, Platform{body.OS, body.Arch})\n\t}\n\n\tdownloadURL, err := url.Parse(body.DownloadURL)\n\tif err != nil {\n\t\treturn PackageMeta{}, fmt.Errorf(\"registry response includes invalid download URL: %s\", err)\n\t}\n\tdownloadURL = resp.Request.URL.ResolveReference(downloadURL)\n\tif downloadURL.Scheme != \"http\" && downloadURL.Scheme != \"https\" {\n\t\treturn PackageMeta{}, fmt.Errorf(\"registry response includes invalid download URL: must use http or https scheme\")\n\t}\n\n\tret := PackageMeta{\n\t\tProvider:         provider,\n\t\tVersion:          version,\n\t\tProtocolVersions: protoVersions,\n\t\tTargetPlatform: Platform{\n\t\t\tOS:   body.OS,\n\t\t\tArch: body.Arch,\n\t\t},\n\t\tFilename: body.Filename,\n\t\tLocation: PackageHTTPURL(downloadURL.String()),\n\t\t// \"Authentication\" is populated below\n\t}\n\n\tif len(body.SHA256Sum) != sha256.Size*2 { // *2 because it's hex-encoded\n\t\treturn PackageMeta{}, c.errQueryFailed(\n\t\t\tprovider,","sourceCodeStart":271,"sourceCodeEnd":307,"githubUrl":"https://github.com/hashicorp/terraform/blob/d32a084675427f5ac3f7d2868578ef8b2c1dc525/internal/getproviders/registry_client.go#L271-L307","documentation":"Thrown when the resolved download URL's scheme is neither http nor https. The download URL is resolved against the request URL first, so a relative path against an https base normally yields https; this fires when the absolute scheme is file/data/javascript/etc.","triggerScenarios":"downloadURL.Scheme is not 'http' and not 'https' after resp.Request.URL.ResolveReference(downloadURL).","commonSituations":"Registry returns a file:// URL; download_url is empty and resolves to the base with no path producing an unexpected scheme; a mirror serving data: URIs; SSRF-hardening failure on the registry side.","solutions":["Ensure the registry serves download_url over http(s) only","If self-hosting, publish artifacts behind an https endpoint","Report a non-http(s) download_url as a registry defect"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"u, err := url.Parse(body.DownloadURL)\nif err != nil {\n    return err\n}\nif u.Scheme != \"http\" && u.Scheme != \"https\" {\n    return fmt.Errorf(\"download_url must be http(s), got %q\", u.Scheme)\n}","typeGuard":"func IsHTTPURL(s string) bool {\n    u, err := url.Parse(s)\n    return err == nil && (u.Scheme == \"http\" || u.Scheme == \"https\")\n}","tryCatchPattern":"if downloadURL.Scheme != \"http\" && downloadURL.Scheme != \"https\" {\n    return fmt.Errorf(\"refusing non-http(s) download URL %q\", downloadURL)\n}","preventionTips":["Serve provider artifacts over https only","Treat file:// or data: download URLs as a registry defect"],"tags":["registry","url","scheme","download","provider","validation"],"backgroundTag":null,"analyzedSha":"d32a084675427f5ac3f7d2868578ef8b2c1dc525","analyzedAt":"2026-08-11T18:43:52.779Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}