hashicorp/packer · error

failed reading response body for %s: %w

Error message

failed reading response body for %s: %w

What it means

After a 200 response for the SHA256SUMS file, io.ReadAll failed while draining resp.Body — the connection dropped or a read/timeout error occurred mid-transfer. The checksum content could not be fully retrieved, so downloadChecksumFile aborts and wraps the underlying read error (typically an io.ReadError, unexpected EOF, or context deadline).

Source

Thrown at provisioner/hcp-sbom/packer_release_fetch.go:163

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)
	}

	return string(body), nil
}

func isValidSHA256Hex(s string) bool {
	if len(s) != 64 {
		return false
	}
	_, err := hex.DecodeString(s)
	return err == nil
}

func expectedZipSHA256FromSums(sumsContent, fileName string) (string, error) {
	for _, line := range strings.Split(sumsContent, "\n") {

View on GitHub (pinned to eb36e3c3e4)

Solutions

  1. Simply retry — downloadPackerRelease already retries the full flow 3 times with a 5s delay, and this error is usually transient
  2. Increase the http.Client timeout (currently 5 minutes in downloadPackerRelease) or the context deadline if on very slow links
  3. Check for middleboxes (proxy, TLS-inspection firewall, VPN) resetting connections to releases.hashicorp.com and bypass them
  4. Check server-side logs or HashiCorp status if resets correlate with service incidents

Example fix

// before: client built inline with fixed timeout
client := &http.Client{Timeout: 5 * time.Minute}
// after: larger timeout for constrained networks
client := &http.Client{Timeout: 15 * time.Minute}
Defensive patterns

Strategy: retry

Validate before calling

// preflight: confirm the checksums endpoint responds and completes a full small read
resp, err := client.Get(shaSumsURL)
if err != nil {
    return fmt.Errorf("checksums endpoint unreachable: %w", err)
}
if resp.StatusCode != http.StatusOK {
    _ = resp.Body.Close()
    return fmt.Errorf("unexpected status %d probing %s", resp.StatusCode, shaSumsURL)
}
n, err := io.Copy(io.Discard, resp.Body)
_ = resp.Body.Close()
if err != nil {
    return fmt.Errorf("connection to %s unstable (read %d bytes then failed): %w", shaSumsURL, n, err)
}

Type guard

// identify read/timeout errors from the body as transient network problems
func isBodyReadError(err error) bool {
    var ne net.Error
    if errors.As(err, &ne) && ne.Timeout() {
        return true
    }
    return errors.Is(err, io.ErrUnexpectedEOF) || errors.Is(err, io.EOF) || errors.Is(err, syscall.ECONNRESET)
}

Try / catch

sums, err := downloadChecksumFile(ctx, client, shaSumsURL)
if err != nil {
    if isBodyReadError(errors.Unwrap(errors.Unwrap(err))) || isBodyReadError(err) {
        return retryErr{err} // transient mid-body disconnect; retry
    }
    return err
}

Prevention

When it happens

Trigger: io.ReadAll(resp.Body) returns err after a 200 response for <base>/packer/<v>/packer_<v>_SHA256SUMS — server closed the connection mid-body, TLS record corruption, an idle-timeout reset from a proxy/LB, or the request context expired during the body read.

Common situations: Flaky network or VPN dropping long-lived connections; an aggressive proxy/load balancer idle timeout; context deadline expiring on a slow link; TLS interception appliances resetting streams; transient releases.hashicorp.com connection resets.

Related errors


AI-assisted analysis of hashicorp/packer@eb36e3c3e4 (2026-09-05). Data as JSON: /api/errors/d840b2b057a33fc6. Report an issue: GitHub.