{"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":"validation","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/c9def3e214014c1188faabfc4a5bde5095139765/internal/getproviders/registry_client.go#L271-L307","documentation":"PackageMeta parsed download_url successfully but its scheme is neither http nor https. Terraform only fetches provider archives over http(s), so the response is rejected outright with a plain fmt.Errorf. This guards against a compromised or misconfigured registry redirecting downloads to file://, ftp://, etc.","triggerScenarios":"Registry response's download_url uses a scheme other than http/https — e.g. file://, ftp://, s3://, or a schemeless URL that resolved oddly.","commonSituations":"Private registry serving artifacts from object storage and emitting an s3:// URL; misconfigured proxy rewriting to ftp; registry dev environment using file:// paths; CDN returning a data: URL.","solutions":["Configure the registry to return an https:// URL for the archive (front object storage with an https endpoint if needed).","If relative, ensure the request URL itself is http(s) so resolution yields an http(s) absolute URL.","Audit any URL-rewriting proxy between Terraform and the registry."],"exampleFix":"// before\n{\"download_url\":\"file:///srv/providers/foo.zip\"}\n// after\n{\"download_url\":\"https://registry.example/providers/foo.zip\"}","handlingStrategy":"validation","validationCode":"// If you control the registry, assert the scheme before returning the response.\nfunc validDownloadScheme(u string) error {\n    parsed, err := url.Parse(u)\n    if err != nil {\n        return err\n    }\n    if parsed.Scheme != \"http\" && parsed.Scheme != \"https\" {\n        return fmt.Errorf(\"download_url scheme %q not allowed\", parsed.Scheme)\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"meta, err := client.PackageMeta(ctx, provider, ver, plat)\nif err != nil && strings.Contains(err.Error(), \"must use http or https scheme\") {\n    // registry tried to redirect to a disallowed scheme; flag as config/registry bug\n}","preventionTips":["Serve all artifacts over https only.","Front object storage with an https endpoint rather than emitting s3:// or file:// URLs.","Review any reverse proxy that could rewrite the scheme."],"tags":["terraform","registry","download-url","security","scheme"],"analyzedSha":"c9def3e214014c1188faabfc4a5bde5095139765","analyzedAt":"2026-08-07T15:39:49.278Z","schemaVersion":2},"datasetVersion":"2026-08-07T21:17:07.882Z"}