hashicorp/packer · error
failed to open downloaded zip: %w
Error message
failed to open downloaded zip: %w
What it means
Wrapped when zip.OpenReader cannot open the downloaded release zip. The file downloaded but is not a readable zip archive — typically because it is corrupt/truncated, or because the server returned an error page (HTML/JSON) with a 200 status that got saved as the 'zip'.
Source
Thrown at provisioner/hcp-sbom/packer_release_fetch.go:276
actualSHA, err := fileSHA256(candidateZipPath)
if err != nil {
return err
}
if !strings.EqualFold(expectedSHA, actualSHA) {
return fmt.Errorf("checksum mismatch for %s: expected %s, got %s", fileName, expectedSHA, actualSHA)
}
// Validate the expected binary exists inside the archive.
binaryName := "packer"
if goos == "windows" {
binaryName = "packer.exe"
}
zr, err := zip.OpenReader(candidateZipPath)
if err != nil {
return fmt.Errorf("failed to open downloaded zip: %w", err)
}
defer func() { _ = zr.Close() }()
foundBinary := false
for _, f := range zr.File {
if f.Name == binaryName {
foundBinary = true
break
}
}
if !foundBinary {
return fmt.Errorf("packer binary %q not found in release zip %s", binaryName, zipURL)
}
keepCandidate = true
zipPath = candidateZipPath
return nil
})View on GitHub (pinned to eb36e3c3e4)
Solutions
- Inspect the temp file contents (e.g. `file packer-dl-*.zip` or head it) to see what was actually downloaded.
- Bypass or fix HTTP proxies/captive portals that may inject HTML with 200 status.
- Re-run the build to get a fresh download; free disk space if the disk is full.
- Check checksum error patterns in earlier logs to correlate corruption timing.
Example fix
// diagnostic before retrying
if b, err := os.ReadFile(candidateZipPath); err == nil && len(b) > 4 {
log.Printf("zip magic bytes: %x", b[:4]) // expect 504b0304 ('PK\x03\x04')
} Defensive patterns
Strategy: validation
Validate before calling
f, err := os.Open(zipPath)
if err != nil {
return err
}
magic := make([]byte, 4)
io.ReadFull(f, magic)
f.Close()
if !bytes.Equal(magic, []byte{0x50, 0x4B, 0x03, 0x04}) {
return fmt.Errorf("downloaded file is not a zip (magic %x); likely an error page saved with HTTP 200", magic)
} Try / catch
if err := run(); err != nil {
if strings.Contains(err.Error(), "failed to open downloaded zip") {
// inspect the temp file content, fix proxy, then retry the download
}
} Prevention
- Bypass proxies/captive portals that return 200 HTML pages
- Check Content-Type is application/zip when pre-flighting the URL
- Keep adequate free space in TMPDIR to avoid truncated writes
- Retry corrupted downloads once before investigating infra
When it happens
Trigger: zip.OpenReader(candidateZipPath) returns a non-nil error on the just-downloaded temp file — invalid zip signature, truncated archive, or non-zip content saved by downloadURLToTempFile.
Common situations: Proxy/captive portal returning a 200 HTML block page instead of the zip; interrupted transfer that still produced a 200; CDN serving garbage; disk corruption in /tmp; extremely constrained disk causing partial writes.
Related errors
- Error creating zip: %s
- Failed to add zip header for %s: %s
- packer binary %q not found in release zip %s
- extract file: %w
- Error creating tar: %s
AI-assisted analysis of hashicorp/packer@eb36e3c3e4 (2026-09-05).
Data as JSON: /api/errors/45663cce975704b8.
Report an issue: GitHub.