hashicorp/packer · error
failed to build request for %s: %w
Error message
failed to build request for %s: %w
What it means
downloadChecksumFile builds an http.Request via http.NewRequestWithContext before fetching the SHA256SUMS file. This error wraps the parse/validation error returned when the URL string is malformed or cannot be turned into a request (e.g. net/url.Parse failure or unsupported scheme). It fires before any network I/O, so the checksum file was never requested.
Source
Thrown at provisioner/hcp-sbom/packer_release_fetch.go:148
_, copyErr := io.Copy(f, resp.Body)
closeErr := f.Close()
if copyErr != nil {
_ = os.Remove(tmpPath)
return "", fmt.Errorf("failed to write download: %w", copyErr)
}
if closeErr != nil {
_ = os.Remove(tmpPath)
return "", fmt.Errorf("failed to close temp file: %w", closeErr)
}
return tmpPath, nil
}
// downloadChecksumFile fetches the SHA256SUMS text file at url.
func downloadChecksumFile(ctx context.Context, client *http.Client, url string) (string, error) {
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
if err != nil {
return "", fmt.Errorf("failed to build request for %s: %w", url, err)
}
resp, err := client.Do(req)
if err != nil {
return "", fmt.Errorf("failed to download %s: %w", url, err)
}
defer func() { _ = resp.Body.Close() }()
if resp.StatusCode != http.StatusOK {
return "", fmt.Errorf("download failed: HTTP %d for %s", resp.StatusCode, url)
}
body, err := io.ReadAll(resp.Body)
if err != nil {
return "", fmt.Errorf("failed reading response body for %s: %w", url, err)
}
if len(strings.TrimSpace(string(body))) == 0 {
return "", fmt.Errorf("empty response body for %s", url)View on GitHub (pinned to eb36e3c3e4)
Solutions
- Inspect the URL printed in the error message and correct it — it must be absolute with an http:// or https:// scheme and valid percent-encoding
- Verify the release base URL override has no leading/trailing spaces, control characters, or missing scheme
- Sanitize/validate the base URL with net/url.Parse before passing it into the download flow
- If the URL looks correct, check the version string used in interpolation for embedded whitespace
Example fix
// before
base := "releases.hashicorp.com" // missing scheme -> parse error
// after
base := "https://releases.hashicorp.com" // absolute URL with valid scheme
if _, err := url.Parse(base); err != nil {
log.Fatalf("invalid release base URL: %v", err)
} Defensive patterns
Strategy: validation
Validate before calling
// validate the release base URL before it reaches downloadChecksumFile
u, err := url.Parse(base)
if err != nil {
return fmt.Errorf("invalid release base URL %q: %w", base, err)
}
if u.Scheme != "http" && u.Scheme != "https" {
return fmt.Errorf("release base URL %q must use http or https", base)
}
if u.Host == "" {
return fmt.Errorf("release base URL %q has no host", base)
} Type guard
func isValidHTTPURL(s string) bool {
u, err := url.Parse(s)
return err == nil && (u.Scheme == "http" || u.Scheme == "https") && u.Host != ""
} Try / catch
// unwrap and classify the cause for clear diagnostics
_, err := downloadChecksumFile(ctx, client, shaSumsURL)
if err != nil {
var ue *url.Error
if errors.As(err, &ue) && ue.Op == "parse" {
return fmt.Errorf("malformed checksum URL: %w", err)
}
return err
} Prevention
- Always use absolute URLs with an explicit https:// scheme for the release base
- Trim user/CI-supplied base URLs of whitespace before use
- Never interpolate untrusted strings directly into URLs without url.Parse validation
- Keep defaultReleaseBaseURL untouched unless you fully control the mirror
- Add a startup-time check of the configured base URL
When it happens
Trigger: http.NewRequestWithContext(ctx, http.MethodGet, url, nil) returns err for the SHA256SUMS URL — a URL that fails net/url parsing (control characters, invalid percent-encoding, spaces) or a scheme other than http/https. In this code path the URL is built as base + "/packer/" + v + "/packer_" + v + "_SHA256SUMS", so only a corrupt base URL produces it in normal operation.
Common situations: A custom/test release base URL containing invalid characters or missing a scheme (e.g. "releases.hashicorp.com" instead of "https://releases.hashicorp.com"); interpolation injecting whitespace or newline into the URL; typos when overriding defaultReleaseBaseURL in modified builds.
Understand the failure class
Background: "Invalid URL" / "URL cannot be empty": fix the malformed or missing URL behind request-construction failures — this error's family across 50 libraries.
Related errors
- create GitHub OIDC request: %w
- request GitHub OIDC token: %w
- request GitHub OIDC token: unexpected status %s
- failed to download %s: %w
- download failed: HTTP %d for %s
AI-assisted analysis of hashicorp/packer@eb36e3c3e4 (2026-09-05).
Data as JSON: /api/errors/85f5d743a991161a.
Report an issue: GitHub.