hashicorp/packer · error

empty response body for %s

Error message

empty response body for %s

What it means

downloadChecksumFile in provisioner/hcp-sbom/packer_release_fetch.go downloads a SHA256SUMS text file from releases.hashicorp.com and requires non-whitespace-only content. When the HTTP response succeeds (status 200) but the body contains only whitespace or nothing, the function rejects it with this error rather than returning an empty checksum list. This guards the downstream parser (expectedZipSHA256FromSums) from silently returning 'checksum not found' for a bogus empty file.

Source

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

		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") {
		fields := strings.Fields(strings.TrimSpace(line))
		if len(fields) < 2 {
			continue

View on GitHub (pinned to eb36e3c3e4)

Solutions

  1. Retry the download — downloadPackerRelease wraps calls in a retry.Config with 3 tries and 5s delay, so transient empty responses are often resolved on retry; the error will surface only after retries are exhausted.
  2. Check network path (proxy/VPN/firewall) for body-stripping behavior; bypass the proxy or add releases.hashicorp.com to an allowlist.
  3. Verify the SHA256SUMS URL manually (curl -v <url>) to confirm the server actually serves checksum content; if the URL is wrong, fix the release base URL / version string used to build it.
  4. If self-hosting a mirror, ensure the SHA256SUMS file is populated and served with correct content.

Example fix

// before: failing against an empty body from a stub server
sumsContent, err := downloadChecksumFile(ctx, client, shaSumsURL)

// after: pre-check the endpoint and add explicit diagnostic logging
resp, err := http.Get(shaSumsURL)
if err == nil {
    log.Printf("SHA256SUMS endpoint status=%d content-length=%d", resp.StatusCode, resp.ContentLength)
}
sumsContent, err := downloadChecksumFile(ctx, client, shaSumsURL)
Defensive patterns

Strategy: retry

Validate before calling

resp, err := http.Head(shaSumsURL)
if err != nil {
    return fmt.Errorf("checksum endpoint unreachable: %w", err)
}
if resp.ContentLength == 0 {
    return fmt.Errorf("SHA256SUMS endpoint reports zero-length body: %s", shaSumsURL)
}

Type guard

func hasNonEmptyBody(body []byte) bool {
    return len(strings.TrimSpace(string(body))) > 0
}

Try / catch

sumsContent, err := downloadChecksumFile(ctx, client, shaSumsURL)
if err != nil {
    if strings.Contains(err.Error(), "empty response body") {
        // transient/proxy issue: back off and retry once more
        time.Sleep(5 * time.Second)
        sumsContent, err = downloadChecksumFile(ctx, client, shaSumsURL)
    }
    if err != nil {
        return fmt.Errorf("cannot fetch SHA256SUMS: %w", err)
    }
}

Prevention

When it happens

Trigger: downloadChecksumFile(ctx, client, url) receives an HTTP 200 response whose body, after strings.TrimSpace, has length 0 — e.g. the SHA256SUMS URL exists but serves an empty file, a proxy/CDN returns a 200 with a zero-length body, or a captive portal/interception proxy strips the body.

Common situations: Corporate proxies or SSL-inspecting firewalls returning empty 200 responses; a misconfigured or deprecated release mirror that still answers 200; transient CDN issues at releases.hashicorp.com; pointing a custom release base URL at a stub server that returns empty bodies.

Related errors


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