hashicorp/packer · error
HTTP request failed: %w
Error message
HTTP request failed: %w
What it means
After building the GET request for the release artifact, downloadURLToTempFile performs client.Do(req) to download the zip from releases.hashicorp.com. If the HTTP exchange itself fails — before any status code is even available — the temp file is closed and removed and this error is returned with the underlying net/http error wrapped. It indicates a transport-level problem: DNS, TCP, TLS, timeout, or cancelled context, not an HTTP error status (a non-200 yields 'HTTP %d for %s' instead).
Source
Thrown at provisioner/hcp-sbom/packer_release_fetch.go:120
func downloadURLToTempFile(ctx context.Context, client *http.Client, url, suffix string) (string, error) {
f, err := os.CreateTemp("", "packer-dl-*"+suffix)
if err != nil {
return "", fmt.Errorf("failed to create temp file: %w", err)
}
tmpPath := f.Name()
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
if err != nil {
_ = f.Close()
_ = os.Remove(tmpPath)
return "", err
}
resp, err := client.Do(req)
if err != nil {
_ = f.Close()
_ = os.Remove(tmpPath)
return "", fmt.Errorf("HTTP request failed: %w", err)
}
defer func() { _ = resp.Body.Close() }()
if resp.StatusCode != http.StatusOK {
_ = f.Close()
_ = os.Remove(tmpPath)
return "", fmt.Errorf("HTTP %d for %s", resp.StatusCode, url)
}
_, 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)View on GitHub (pinned to eb36e3c3e4)
Solutions
- Read the wrapped cause in the message and verify basic reachability: curl -v https://releases.hashicorp.com/packer/ from the build machine.
- Check DNS on the machine (nslookup releases.hashicorp.com) and fix resolver config if it fails.
- If behind a corporate proxy, set HTTPS_PROXY/HTTP_PROXY for the process or configure the http.Client Transport's Proxy.
- Retry the build — downloadPackerRelease already retries 3 times with 5s delay, so persistent failure means the network path, not transience, is broken.
- Check firewall/egress rules to allow HTTPS (443) to releases.hashicorp.com, and confirm the context isn't being cancelled by an outer timeout that is too short.
Example fix
// before: fail hard when the download cannot reach the network
path, err := downloadURLToTempFile(ctx, client, zipURL, ".zip")
// after: surface and handle transient network errors with your own bounded retry
var path string
err = retry.Config{Tries: 5, RetryDelay: func() time.Duration { return 10 * time.Second }}.
Run(ctx, func(ctx context.Context) error {
p, err := downloadURLToTempFile(ctx, client, zipURL, ".zip")
if err != nil && isRetryableNetErr(err) { return err }
if err != nil { return retry.Fatal(err) }
path = p
return nil
}) Defensive patterns
Strategy: retry
Validate before calling
// Pre-flight reachability check before starting the download flow
func reachable(endpoint string) error {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
req, _ := http.NewRequestWithContext(ctx, http.MethodHead, endpoint, nil)
resp, err := http.DefaultClient.Do(req)
if err != nil {
return fmt.Errorf("releases host unreachable: %w", err)
}
resp.Body.Close()
return nil
} Try / catch
var path string
err := retry.Config{
Tries: 4,
RetryDelay: func() time.Duration { return 10 * time.Second },
}.Run(ctx, func(ctx context.Context) error {
p, err := downloadURLToTempFile(ctx, client, url, ".zip")
if err == nil {
path = p
return nil
}
if strings.HasPrefix(err.Error(), "HTTP ") {
return retry.Fatal(err) // server responded: status errors are not transient
}
return err // transport error: safe to retry
})
if err != nil {
return fmt.Errorf("download failed after retries: %w", err)
} Prevention
- Allow egress to releases.hashicorp.com:443 in firewalls/CI network policies.
- Configure HTTPS_PROXY on build agents that sit behind corporate proxies.
- Give long downloads a generous deadline; the default client timeout here is 5 minutes.
- Run preflight DNS/connectivity checks at CI job start to fail fast with a clear message.
- Rely on bounded retries (the caller already retries 3x) instead of single-shot downloads on flaky networks.
When it happens
Trigger: client.Do returns an error: DNS resolution failure for releases.hashicorp.com, connection refused/timeout, TLS handshake/certificate errors, the 5-minute client timeout elapses mid-transfer, the context is cancelled, or a proxy is unreachable.
Common situations: Build agents without internet access or behind a corporate proxy that requires configuration; DNS misconfiguration; transient network flaps between retries; firewall or egress rules blocking releases.hashicorp.com; slow links exceeding the 5-minute HTTP client timeout while downloading large zips.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
- failed to download %s: %w
- failed to fetch release index: %w
- request GitHub OIDC token: %w
- Error reading checksum file: %s
- failed to build index request: %w
AI-assisted analysis of hashicorp/packer@eb36e3c3e4 (2026-09-05).
Data as JSON: /api/errors/4a6c1a42e6eac35b.
Report an issue: GitHub.