hashicorp/terraform · critical · ErrChecksumDoesNotMatch

downloaded archive does not match the release checksum

Error message

downloaded archive does not match the release checksum

What it means

ErrChecksumDoesNotMatch is returned by ChecksumAuthentication.Authenticate after SHA-256 hashing the on-disk archive and finding the digest does not equal the expected hash supplied at construction. The comment on the type stresses that the expected checksum itself must already be trusted (typically because it came from a signature-verified SHA256SUMS file) — this authenticator only proves the bytes match, not that the checksum is authentic.

Source

Thrown at internal/releaseauth/checksum.go:28

	"fmt"
	"io"
	"log"
	"os"
)

// ChecksumAuthentication is an archive Authenticator that ensures a given file
// matches a SHA-256 checksum. It is important to verify the authenticity of the
// given checksum prior to using this Authenticator.
type ChecksumAuthentication struct {
	Authenticator

	expected        SHA256Hash
	archiveLocation string
}

// ErrChecksumDoesNotMatch is the error returned when the archive checksum does
// not match the given checksum.
var ErrChecksumDoesNotMatch = errors.New("downloaded archive does not match the release checksum")

// NewChecksumAuthentication creates an instance of ChecksumAuthentication with the given
// checksum and file location.
func NewChecksumAuthentication(expected SHA256Hash, archiveLocation string) *ChecksumAuthentication {
	return &ChecksumAuthentication{
		expected:        expected,
		archiveLocation: archiveLocation,
	}
}

func (a ChecksumAuthentication) Authenticate() error {
	f, err := os.Open(a.archiveLocation)
	if err != nil {
		return fmt.Errorf("failed to open downloaded archive: %w", err)
	}
	defer f.Close()

	h := sha256.New()

View on GitHub (pinned to d32a084675)

Solutions

  1. Re-download the archive cleanly (delete the partial file first) and re-authenticate.
  2. Confirm the expected SHA256Hash was extracted from the correct release's SHA256SUMS entry for this exact filename.
  3. If the checksum in SHA256SUMS is genuinely wrong, the release is broken — report it; do not weaken verification.
  4. Verify the SHA256SUMS file itself was signature-authenticated (SignatureAuthentication) before trusting its contents.

Example fix

// before
auth := releaseauth.NewChecksumAuthentication(expectedHash, archivePath)
if err := auth.Authenticate(); err != nil {
    return err // re-using a possibly-corrupt file
}

// after — remove partial then re-download before authenticating
_ = os.Remove(archivePath)
if err := redownload(archivePath); err != nil {
    return err
}
auth := releaseauth.NewChecksumAuthentication(expectedHash, archivePath)
if err := auth.Authenticate(); err != nil {
    return fmt.Errorf("archive checksum mismatch after fresh download: %w", err)
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Hash before authenticating to give a clearer error
f, _ := os.Open(archivePath)
h := sha256.New()
io.Copy(h, f)
actual := hex.EncodeToString(h.Sum(nil))
expected := hex.EncodeToString(expectedHash[:])
if actual != expected {
    log.Printf("expected %s got %s", expected, actual)
}

Type guard

func isChecksumMismatch(err error) bool {
    return errors.Is(err, releaseauth.ErrChecksumDoesNotMatch)
}

Try / catch

err := releaseauth.NewChecksumAuthentication(expected, path).Authenticate()
if errors.Is(err, releaseauth.ErrChecksumDoesNotMatch) {
    _ = os.Remove(path) // discard corrupt archive
    return redownloadAndAuthenticate(path, expected)
}

Prevention

When it happens

Trigger: NewChecksumAuthentication(expected, path).Authenticate() reads archiveLocation, hashes it with SHA-256, and at checksum.go:54 compares gotHash to a.expected[:]; on mismatch it returns ErrChecksumDoesNotMatch.

Common situations: Truncated or corrupted download (network error mid-transfer); tampered/ MitM-modified archive; expected hash taken from the wrong release's SHA256SUMS; partial write left on disk from a previous failed download.

Related errors


AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11). Data as JSON: /api/errors/6d6c929da1d85d82. Report an issue: GitHub.