goreleaser/goreleaser · error

could not pack %s: %w: %s

Error message

could not pack %s: %w: %s

What it means

The upx pipe compresses binaries with the external upx tool. If upx exits non-zero, goreleaser wraps the command error plus upx's combined output (string(out)). So this message contains both the Go-level failure and upx's own diagnostic text — read the trailing text to learn why upx refused the binary.

Source

Thrown at internal/pipe/upx/upx.go:93

	}
	if upx.LZMA {
		args = append(args, "--lzma")
	}
	if upx.Brute {
		args = append(args, "--brute")
	}
	args = append(args, bin.Path)
	out, err := exec.CommandContext(ctx, upx.Binary, args...).CombinedOutput()
	if err != nil {
		for _, ke := range knownExceptions {
			if strings.Contains(string(out), ke) {
				log.WithField("binary", bin.Path).
					WithField("exception", ke).
					Warn("could not pack")
				return nil
			}
		}
		return fmt.Errorf("could not pack %s: %w: %s", bin.Path, err, string(out))
	}

	sizeAfter := sizeOf(bin.Path)

	log.
		WithField("before", units.HumanSize(float64(sizeBefore))).
		WithField("after", units.HumanSize(float64(sizeAfter))).
		WithField("ratio", fmt.Sprintf("%d%%", (sizeAfter*100)/sizeBefore)).
		WithField("binary", bin.Path).
		Info("packed")

	return nil
}

var knownExceptions = []string{
	"CantPackException",
	"AlreadyPackedException",
	"NotCompressibleException",

View on GitHub (pinned to f5edd73956)

Solutions

  1. Read the trailing `%s` output in the message — it contains upx's actual reason
  2. Install/upgrade upx to a version supporting your target platform (upx >= 4.x for arm64 Darwin)
  3. Set the binary as an ignorable exception or disable upx for that binary id (upx: enabled: false or use `upx.ids` filtering)
  4. Ensure the binary is not already packed and is a valid executable for the host arch running upx

Example fix

# before
upx:
  enabled: true
# after (skip binaries upx cannot pack)
upx:
  enabled: true
  ids: [linux-amd64-bin] # exclude darwin/arm64 which upx may reject
Defensive patterns

Strategy: fallback

Validate before calling

# pre-flight: is upx usable for this arch?
upx --version || echo 'upx missing'
file dist/mybin # confirm architecture upx build supports

Try / catch

if err := compress(bin); err != nil {
	log.Warnf("upx failed for %s, shipping uncompressed: %v", bin, err)
	return shipUncompressed(bin) // fallback
}

Prevention

When it happens

Trigger: compressOne runs upx on a built binary and the upx process returns an error and non-empty output that is not classified as ignorable (the code path above returns nil only for specific known exceptions like AlreadyPackedException/ CoronaException).

Common situations: upx not installed or wrong version in PATH (command not found output); archiving binaries upx cannot handle (e.g. certain arm64/M1 builds, signed binaries, Go binaries of some versions); already-packed binary; corrupted partial output file.

Related errors


AI-assisted analysis of goreleaser/goreleaser@f5edd73956 (2026-09-05). Data as JSON: /api/errors/99ad81982b3599cc. Report an issue: GitHub.