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

  1. Inspect the zip: `unzip -l <localZipPath>` — confirm an entry named exactly `packer` exists at the root.
  2. Redownload the Packer release zip; verify checksum/integrity to rule out a corrupt or truncated download.
  3. Use the correct platform's zip (linux/amd64 etc.) whose root contains `packer`, not an archive with a nested directory.
  4. Extract the binary yourself and point the provisioning pipeline at a zip laid out as expected, or place `packer` at the zip root.
  5. 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

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


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