hashicorp/terraform · error

provider package doesn't match the expected checksum %q

Error message

provider package doesn't match the expected checksum %q

What it means

Single-hash mismatch from packageHashAuthentication.AuthenticatePackage. Exactly one RequiredHash was acceptable to this binary, the package was successfully hashed, but PackageMatchesAnyHash returned false. The '%q' is the one expected hash (its full 'h1:'/'zh:' string). This is an integrity failure: the bytes on disk do not match the locked/declared checksum.

Source

Thrown at internal/getproviders/package_authentication.go:259

func (a packageHashAuthentication) AuthenticatePackage(localLocation PackageLocation) (*PackageAuthenticationResult, error) {
	if len(a.RequiredHashes) == 0 {
		// Indicates that none of the hashes given to
		// NewPackageHashAuthentication were considered to be usable by this
		// version of Terraform.
		return nil, fmt.Errorf("this version of Terraform does not support any of the checksum formats given for this provider")
	}

	matches, err := PackageMatchesAnyHash(localLocation, a.RequiredHashes)
	if err != nil {
		return nil, fmt.Errorf("failed to verify provider package checksums: %s", err)
	}

	if matches {
		return &PackageAuthenticationResult{result: verifiedChecksum}, nil
	}
	if len(a.RequiredHashes) == 1 {
		return nil, fmt.Errorf("provider package doesn't match the expected checksum %q", a.RequiredHashes[0].String())
	}
	// It's non-ideal that this doesn't actually list the expected checksums,
	// but in the many-checksum case the message would get pretty unweildy.
	// In practice today we typically use this authenticator only with a
	// single hash returned from a network mirror, so the better message
	// above will prevail in that case. Maybe we'll improve on this somehow
	// if the future introduction of a new hash scheme causes there to more
	// commonly be multiple hashes.
	return nil, fmt.Errorf("provider package doesn't match the any of the expected checksums")
}

func (a packageHashAuthentication) AcceptableHashes() []Hash {
	// In this case we include even hashes the current version of Terraform
	// doesn't prefer, because this result is used for building a lock file
	// and so it's helpful to include older hash formats that other Terraform
	// versions might need in order to do authentication successfully.
	return a.AllHashes
}

View on GitHub (pinned to c9def3e214)

Solutions

  1. Confirm the expected hash in the error matches the lock file / mirror; if the mirror's hash is wrong, update or replace the mirror.
  2. Re-download the package: purge .terraform/providers and the plugin cache, then 'terraform init'.
  3. If you control the mirror, recompute and republish the correct 'h1:' hash for the served artifact.
  4. Verify the version string is not ambiguous (e.g. a provider re-released at the same version with different bytes); pin to a specific build or update the lock entry to match the current artifact.

Example fix

// before: lock pinned to a stale hash
hashes = ["h1:OLDHASH..."]
// after: regenerate the lock against the real artifact
$ rm .terraform.lock.hcl && terraform init
Defensive patterns

Strategy: validation

Validate before calling

// Recompute the hash locally and compare to the lock entry before trusting a mirror.
computed, err := getproviders.PackageHashV1(loc)
if err != nil { return err }
if computed != expected { return fmt.Errorf("staged package hash %s != expected %s", computed, expected) }

Try / catch

_, err := auth.AuthenticatePackage(loc)
if err != nil {
    if strings.Contains(err.Error(), "doesn't match the expected checksum") {
        // integrity drift: do NOT silently proceed. Purge cache + re-init or fail.
    }
    return err
}

Prevention

When it happens

Trigger: len(a.RequiredHashes)==1 and PackageMatchesAnyHash returns (false, nil) at line 255, reaching line 259. In practice this is the network-mirror path, which typically supplies a single hash. The package downloaded fine but its computed hash differs from the mirror-provided one.

Common situations: A filesystem mirror whose published hash is stale (points at an older build of the same version). A corrupt or partially-overwritten download that produced a valid but wrong archive. A man-in-the-middle or CDN serving a tampered package. Lock file pinned to a hash that no longer matches the registry artifact after a republish.

Related errors


AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07). Data as JSON: /api/errors/e5618d09ab616c1a. Report an issue: GitHub.