hashicorp/packer · error

extract file: %w

Error message

extract file: %w

What it means

During plugin installation, Packer copies the extracted plugin binary out of the archive reader into an in-memory buffer (io.Copy). If that copy fails at any point, the underlying error is wrapped as "extract file: %w" and accumulated into a multierror returned by InstallLatest. This indicates the compressed archive stream could not be read/decoded for this member file.

Source

Thrown at packer/plugin-getter/plugins.go:874

						if f.Name != expectedBinaryFilename {
							continue
						}
						copyFrom, err = f.Open()
						if err != nil {
							errs = multierror.Append(errs, fmt.Errorf("failed to open temp file: %w", err))
							return nil, errs
						}
						break
					}
					if copyFrom == nil {
						err := fmt.Errorf("could not find a %q file in zipfile", expectedBinaryFilename)
						errs = multierror.Append(errs, err)
						return nil, errs
					}

					var outputFileData bytes.Buffer
					if _, err := io.Copy(&outputFileData, copyFrom); err != nil {
						err := fmt.Errorf("extract file: %w", err)
						errs = multierror.Append(errs, err)
						return nil, errs
					}
					tmpBinFileName := filepath.Join(os.TempDir(), expectedBinaryFilename)
					tmpOutputFile, err := os.OpenFile(tmpBinFileName, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0755)
					if err != nil {
						err = fmt.Errorf("could not create temporary file to download plugin: %w", err)
						errs = multierror.Append(errs, err)
						return nil, errs
					}
					defer func() {
						os.Remove(tmpBinFileName)
					}()

					if _, err := tmpOutputFile.Write(outputFileData.Bytes()); err != nil {
						err := fmt.Errorf("extract file: %w", err)
						errs = multierror.Append(errs, err)
						return nil, errs

View on GitHub (pinned to eb36e3c3e4)

Solutions

  1. Delete the corrupted plugin archive from Packer's plugin directory (~/.packer.d/plugins or PLUGIN_MIN_PORT config dir) and re-run the install so it re-downloads.
  2. Verify connectivity/proxy settings if the archive was fetched from a remote registry; retry the install.
  3. Check free disk space and that the download completed (compare archive size/checksum).
  4. If using a custom plugin, rebuild and re-zip the plugin binary correctly.
  5. Upgrade Packer; if persistent, file an issue with the wrapped (%w) inner error message.
Defensive patterns

Strategy: retry

Validate before calling

// before install: sanity-check the cached/downloaded archive
f, err := os.Open(archivePath)
if err != nil { return err }
defer f.Close()
zr, err := zip.NewReader(bufio.NewReader(f), archiveStat.Size())
if err != nil { return fmt.Errorf("archive unreadable, delete and re-download: %w", err) }
for _, zf := range zr.File {
    rc, err := zf.Open()
    if err != nil { return err }
    _, _ = io.Copy(io.Discard, rc)
    rc.Close()
}

Try / catch

err := getter.InstallLatest(ctx, req)
if err != nil {
    var merr *multierror.Error
    if errors.As(err, &merr) {
        for _, e := range merr.Errors {
            if strings.Contains(e.Error(), "extract file") {
                // purge corrupted archive and retry once
                os.RemoveAll(pluginCacheDir)
                return getter.InstallLatest(ctx, req)
            }
        }
    }
    return err
}

Prevention

When it happens

Trigger: Calling InstallLatest (directly or via `packer plugins installed`/installFromServer) when the reader for a plugin archive member returns an error mid-copy: corrupt zip member, truncated download, or a reader that errors on Read.

Common situations: Corrupted plugin ZIP in the plugin cache or downloaded from a broken mirror/proxy; disk/network failure while streaming the archive; a malformed custom-built plugin binary packaged into the archive.

Related errors


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