{"record":{"id":"f665807ef54fb27e","repo":"hashicorp/packer","slug":"failed-to-extract-s-from-packer-release-zip-w","errorCode":null,"errorMessage":"failed to extract %s from Packer release zip: %w","messagePattern":"failed to extract (.+?) from Packer release zip: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"provisioner/hcp-sbom/provisioner.go","lineNumber":532,"sourceCode":"\t\t\t`powershell -NoProfile -ExecutionPolicy Bypass -Command `+\n\t\t\t\t`\"$ErrorActionPreference='Stop'; `+\n\t\t\t\t`Expand-Archive -Path '%s' -DestinationPath '%s' -Force; `+\n\t\t\t\t`if (!(Test-Path '%s\\%s')) { throw 'packer.exe not found after extraction' }; `+\n\t\t\t\t`Move-Item -Force '%s\\%s' '%s'; `+\n\t\t\t\t`Remove-Item -Force '%s'\"`,\n\t\t\tremoteZipPath, remoteDir,\n\t\t\tremoteDir, binaryName,\n\t\t\tremoteDir, binaryName, remotePath,\n\t\t\tremoteZipPath,\n\t\t)\n\t\tif err := p.runRemoteCmd(ctx, comm, psCmd, \"extract scanner (Windows)\"); err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\t} else {\n\t\t// Step 1: extract the binary locally from the release zip.\n\t\tbinaryData, err := extractBinaryFromZip(localZipPath, binaryName)\n\t\tif err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"failed to extract %s from Packer release zip: %w\", binaryName, err)\n\t\t}\n\n\t\t// Step 2: upload binary directly to remote.\n\t\tlocalFile := bytes.NewReader(binaryData)\n\t\tlog.Printf(\"[INFO] Uploading Packer binary to %s...\", remotePath)\n\t\tif err := comm.Upload(remotePath, localFile, nil); err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"failed to upload Packer binary: %s\", err)\n\t\t}\n\n\t\t// Step 3: make it executable.\n\t\tchmodCmd := fmt.Sprintf(`chmod +x \"%s\"`, remotePath)\n\t\tif err := p.runRemoteCmd(ctx, comm, chmodCmd, \"chmod scanner binary\"); err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\n\t\t// Final verify: confirm binary is executable.\n\t\tverifyCmd := fmt.Sprintf(`test -x \"%s\"`, remotePath)\n\t\tif err := p.runRemoteCmd(ctx, comm, verifyCmd, \"verify scanner is executable\"); err != nil {","sourceCodeStart":514,"sourceCodeEnd":550,"githubUrl":"https://github.com/hashicorp/packer/blob/eb36e3c3e48a036f3e8cc94087636ee72e1303c9/provisioner/hcp-sbom/provisioner.go#L514-L550","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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'."],"exampleFix":"// before: nested layout breaks exact-name lookup\n// zip contains: packer_linux_amd64/packer\n// after: flatten so the entry is at the zip root\ncd packer_linux_amd64 && zip -j /tmp/packer.zip packer","handlingStrategy":"validation","validationCode":"zr, err := zip.OpenReader(localZipPath)\nif err != nil {\n\treturn fmt.Errorf(\"invalid or corrupt zip at %s: %w\", localZipPath, err)\n}\ndefer zr.Close()\nfound := false\nfor _, f := range zr.File {\n\tif f.Name == \"packer\" {\n\t\tfound = true\n\t\tbreak\n\t}\n}\nzr.Close()\nif !found {\n\treturn fmt.Errorf(\"zip %s has no root entry named 'packer'\", localZipPath)\n}","typeGuard":"func hasZipEntry(zipPath, name string) bool {\n\tzr, err := zip.OpenReader(zipPath)\n\tif err != nil {\n\t\treturn false\n\t}\n\tdefer zr.Close()\n\tfor _, f := range zr.File {\n\t\tif f.Name == name {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}","tryCatchPattern":"binaryData, err := extractBinaryFromZip(localZipPath, binaryName)\nif err != nil {\n\tif strings.Contains(err.Error(), \"failed to open zip\") {\n\t\t// redownload/verify the zip\n\t} else {\n\t\t// entry missing: wrong archive layout or platform\n\t}\n\treturn err\n}","preventionTips":["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."],"tags":["zip","file-io","unix","provisioner","hcp-sbom"],"backgroundTag":"zip-entry-not-found","analyzedSha":"eb36e3c3e48a036f3e8cc94087636ee72e1303c9","analyzedAt":"2026-09-05T13:20:43.127Z","contentChangedAt":"2026-09-05T13:20:43.127Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}