hashicorp/packer · error
failed to extract %s from Packer release zip: %w
Error message
failed to extract %s from Packer release zip: %w
What it means
This error wraps a failure from extractBinaryFromZip when uploadScanner tries to pull the `packer` binary out of the local release zip on the Unix path. It is thrown at provisioner/hcp-sbom/provisioner.go:532, called by provisionWithNativeGeneration. It means the zip could not be opened at all (corrupt/missing file) or did not contain an entry exactly named `packer` at the zip root.
Source
Thrown at provisioner/hcp-sbom/provisioner.go:532
`powershell -NoProfile -ExecutionPolicy Bypass -Command `+
`"$ErrorActionPreference='Stop'; `+
`Expand-Archive -Path '%s' -DestinationPath '%s' -Force; `+
`if (!(Test-Path '%s\%s')) { throw 'packer.exe not found after extraction' }; `+
`Move-Item -Force '%s\%s' '%s'; `+
`Remove-Item -Force '%s'"`,
remoteZipPath, remoteDir,
remoteDir, binaryName,
remoteDir, binaryName, remotePath,
remoteZipPath,
)
if err := p.runRemoteCmd(ctx, comm, psCmd, "extract scanner (Windows)"); err != nil {
return "", err
}
} else {
// Step 1: extract the binary locally from the release zip.
binaryData, err := extractBinaryFromZip(localZipPath, binaryName)
if err != nil {
return "", fmt.Errorf("failed to extract %s from Packer release zip: %w", binaryName, err)
}
// Step 2: upload binary directly to remote.
localFile := bytes.NewReader(binaryData)
log.Printf("[INFO] Uploading Packer binary to %s...", remotePath)
if err := comm.Upload(remotePath, localFile, nil); err != nil {
return "", fmt.Errorf("failed to upload Packer binary: %s", err)
}
// Step 3: make it executable.
chmodCmd := fmt.Sprintf(`chmod +x "%s"`, remotePath)
if err := p.runRemoteCmd(ctx, comm, chmodCmd, "chmod scanner binary"); err != nil {
return "", err
}
// Final verify: confirm binary is executable.
verifyCmd := fmt.Sprintf(`test -x "%s"`, remotePath)
if err := p.runRemoteCmd(ctx, comm, verifyCmd, "verify scanner is executable"); err != nil {View on GitHub (pinned to eb36e3c3e4)
Solutions
- Inspect the zip: `unzip -l <localZipPath>` — confirm an entry named exactly `packer` exists at the root.
- Redownload the Packer release zip; verify checksum/integrity to rule out a corrupt or truncated download.
- Use the correct platform's zip (linux/amd64 etc.) whose root contains `packer`, not an archive with a nested directory.
- Extract the binary yourself and point the provisioning pipeline at a zip laid out as expected, or place `packer` at the zip root.
- Run with PACKER_LOG=1 and read the wrapped error to distinguish 'failed to open zip' from 'entry not found'.
Example fix
// before: nested layout breaks exact-name lookup // zip contains: packer_linux_amd64/packer // after: flatten so the entry is at the zip root cd packer_linux_amd64 && zip -j /tmp/packer.zip packer
Defensive patterns
Strategy: validation
Validate before calling
zr, err := zip.OpenReader(localZipPath)
if err != nil {
return fmt.Errorf("invalid or corrupt zip at %s: %w", localZipPath, err)
}
defer zr.Close()
found := false
for _, f := range zr.File {
if f.Name == "packer" {
found = true
break
}
}
zr.Close()
if !found {
return fmt.Errorf("zip %s has no root entry named 'packer'", localZipPath)
} Type guard
func hasZipEntry(zipPath, name string) bool {
zr, err := zip.OpenReader(zipPath)
if err != nil {
return false
}
defer zr.Close()
for _, f := range zr.File {
if f.Name == name {
return true
}
}
return false
} Try / catch
binaryData, err := extractBinaryFromZip(localZipPath, binaryName)
if err != nil {
if strings.Contains(err.Error(), "failed to open zip") {
// redownload/verify the zip
} else {
// entry missing: wrong archive layout or platform
}
return err
} Prevention
- Validate the zip with `unzip -l` (or zip.OpenReader) before provisioning.
- Pin the exact Packer release URL for the target platform and verify its checksum.
- Remember entry matching is exact-name at the zip root; avoid archives with nested directories.
- After upgrading Packer versions, re-check that the archive layout is unchanged.
- Fail the pipeline before provisioning if the expected entry is absent.
When it happens
Trigger: extractBinaryFromZip(localZipPath, "packer") fails: the zip cannot be opened (invalid/corrupt/missing path), or no zip entry with name exactly `packer` exists (entries are matched by exact name, not basename or nested path).
Common situations: The downloaded release zip is for the wrong platform or a different archive layout where the binary sits in a subdirectory (e.g. `packer/packer`), so the exact-name match fails; a partial/corrupt download; the zip path config points at a non-zip file; a release upgrade changed the archive layout.
Related errors
- failed to open Packer release zip: %s
- source must be specified when auto_generate is not enabled
- failed to determine latest Packer version: %w
- Only one of script or scripts can be specified.
- Must supply an 'elevated_user' if 'elevated_password' provid
AI-assisted analysis of hashicorp/packer@eb36e3c3e4 (2026-09-05).
Data as JSON: /api/errors/f665807ef54fb27e.
Report an issue: GitHub.