golangci/golangci-lint · error

failed to calculate binary salt: %w

Error message

failed to calculate binary salt: %w

What it means

initHashSalt computes a binary salt (used for cache invalidation keys) via computeBinarySalt, which locates the running executable and hashes its content/version. Any failure resolving or hashing the binary is wrapped as "failed to calculate binary salt".

Source

Thrown at pkg/commands/run.go:628

func formatMemory(memBytes uint64) string {
	const Kb = 1024
	const Mb = Kb * 1024

	if memBytes < Kb {
		return fmt.Sprintf("%db", memBytes)
	}
	if memBytes < Mb {
		return fmt.Sprintf("%dkb", memBytes/Kb)
	}
	return fmt.Sprintf("%dmb", memBytes/Mb)
}

// Related to cache.

func initHashSalt(logger logutils.Log, version string, cfg *config.Config) error {
	binSalt, err := computeBinarySalt(version)
	if err != nil {
		return fmt.Errorf("failed to calculate binary salt: %w", err)
	}

	configSalt, err := computeConfigSalt(cfg)
	if err != nil {
		return fmt.Errorf("failed to calculate config salt: %w", err)
	}

	goModSalt, err := computeGoModSalt()
	if err != nil {
		// NOTE: missing go.mod must be ignored.
		logger.Warnf("Failed to calculate go.mod salt: %v", err)
	}

	b := bytes.NewBuffer(binSalt)
	b.WriteString("golangci-lint-cache/v2")
	b.Write(configSalt)
	b.WriteString(goModSalt)

View on GitHub (pinned to ed7a235d2d)

Solutions

  1. Re-run the command; transient mid-run binary replacement is the usual cause.
  2. Install/keep the golangci-lint binary on stable storage instead of a temp path (avoid `go run` for repeated cache-dependent runs).
  3. If using a wrapper/symlink, ensure the symlink target exists.
  4. Clear the golangci-lint cache (`golangci-lint cache clean`) after upgrading the binary.

Example fix

// before
go run github.com/golangci/golangci-lint/cmd/golangci-lint run   # temp binary path issues
// after
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
golangci-lint run
Defensive patterns

Strategy: try-catch

Validate before calling

exe, err := os.Executable()
if err != nil {
	return fmt.Errorf("executable path unavailable; binary salt computation will fail")
}
if _, err := os.Stat(exe); err != nil {
	return fmt.Errorf("golangci-lint binary missing at %s", exe)
}

Try / catch

if err := cmd.Run(); err != nil && strings.Contains(err.Error(), "failed to calculate binary salt") {
	log.Printf("binary salt failed (binary replaced/deleted mid-run?); rerun: %v", err)
}

Prevention

When it happens

Trigger: os.Executable() fails or the executable file cannot be read/hashed — e.g. the binary was deleted/replaced mid-run, running via a broken symlink, or an exotic exec environment where the executable path is unavailable.

Common situations: Container images where the binary is removed after entrypoint exec; go run temp binaries being garbage-collected concurrently; unusual sandboxes hiding /proc/self/exe.

Related errors


AI-assisted analysis of golangci/golangci-lint@ed7a235d2d (2026-09-02). Data as JSON: /api/errors/b989f8f3fd89ad82. Report an issue: GitHub.