hashicorp/terraform · error
registry response includes invalid download URL
Error message
registry response includes invalid download URL: %s
What it means
Thrown when the registry's download_url field cannot be parsed as a URL. The download URL is later resolved against the request URL and required to be http/https.
Solutions
- Report the malformed download_url to the registry operator
- If self-hosting, ensure download_url is an absolute http(s) URL
- Check for a misbehaving mirror or proxy that rewrites the field
Defensive patterns
Strategy: validation
Validate before calling
// Pre-validate a URL string parses cleanly.
func parseableURL(s string) bool {
_, err := url.Parse(s)
return err == nil
} Type guard
func IsParseableURL(s string) bool {
_, err := url.Parse(s)
return err == nil
} Try / catch
if _, err := url.Parse(body.DownloadURL); err != nil {
return fmt.Errorf("registry returned an unparseable download_url: %w", err)
} Prevention
- Registries must publish absolute http(s) download URLs
- Sanitize response fields of control characters before parsing
When it happens
Trigger: url.Parse(body.DownloadURL) returned a non-nil error (e.g. control characters, an unparseable scheme).
Common situations: Registry returns a download_url containing whitespace/control characters; a relative path with an unparseable form; corruption of the JSON field in transit.
Related errors
- registry response includes invalid download URL: must use…
- registry response includes invalid SHASUMS signature URL
- registry response includes invalid SHASUMS URL: must use…
- registry response includes invalid SHASUMS URL
- registry response includes invalid SHA256 hash
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/e6eb055ce0a6d0b0.
Report an issue: GitHub.
Appendix: source
Thrown at internal/getproviders/registry_client.go:285
if !match {
// If the protocol version is not supported, try to find the closest
// matching version.
closest, err := c.findClosestProtocolCompatibleVersion(ctx, provider, version)
if err != nil {
return PackageMeta{}, err
}
protoErr.Suggestion = closest
return PackageMeta{}, protoErr
}
}
if body.OS != target.OS || body.Arch != target.Arch {
return PackageMeta{}, fmt.Errorf("registry response to request for %s archive has incorrect target %s", target, Platform{body.OS, body.Arch})
}
downloadURL, err := url.Parse(body.DownloadURL)
if err != nil {
return PackageMeta{}, fmt.Errorf("registry response includes invalid download URL: %s", err)
}
downloadURL = resp.Request.URL.ResolveReference(downloadURL)
if downloadURL.Scheme != "http" && downloadURL.Scheme != "https" {
return PackageMeta{}, fmt.Errorf("registry response includes invalid download URL: must use http or https scheme")
}
ret := PackageMeta{
Provider: provider,
Version: version,
ProtocolVersions: protoVersions,
TargetPlatform: Platform{
OS: body.OS,
Arch: body.Arch,
},
Filename: body.Filename,
Location: PackageHTTPURL(downloadURL.String()),
// "Authentication" is populated below
}View on GitHub (pinned to d32a084675)