hashicorp/terraform · critical · ErrNotSignedByHashiCorp

ErrNotSignedByHashiCorp

ErrNotSignedByHashiCorp

Error message

failed to authenticate that the archive was signed by HashiCorp

What it means

ErrNotSignedByHashiCorp is a sentinel from SignatureAuthentication.Authenticate: it verifies the detached OpenPGP signature of the SHA256SUMS file against the bundled HashiCorp public key (HashiCorpPublicKey, key ID 72D7468F). Any GPG verification failure other than an expired key (which is tolerated and logged) is collapsed into this error, meaning the signature could not be attributed to HashiCorp.

Source

Thrown at internal/releaseauth/signature.go:32

	openpgpErrors "github.com/ProtonMail/go-crypto/openpgp/errors"
)

// SignatureAuthentication is an archive Authenticator that validates that SHA256SUMS data
// was signed by the given signing key.
type SignatureAuthentication struct {
	Authenticator

	// This can be overridden by tests to check arbitrary keys, rather than the HashiCorp public key
	PublicKey string
	signature []byte
	signed    []byte
}

var _ Authenticator = SignatureAuthentication{}

// ErrNotSignedByHashiCorp is the error returned when there is a mismatch between the SHA256SUMS
// signature data and the data itself.
var ErrNotSignedByHashiCorp = errors.New("failed to authenticate that the archive was signed by HashiCorp")

// NewSignatureAuthentication creates a new Authenticator given some signature data
// (the SHA256SUMS.sig file), the signed data (the SHA256SUMS file), and a public key
func NewSignatureAuthentication(signature []byte, signed []byte) *SignatureAuthentication {
	return &SignatureAuthentication{
		signature: signature,
		signed:    signed,
		PublicKey: HashiCorpPublicKey,
	}
}

func (a SignatureAuthentication) Authenticate() error {
	// Verify the signature using the HashiCorp public key. If this succeeds,
	// this is an official provider.
	hashicorpKeyring, err := openpgp.ReadArmoredKeyRing(strings.NewReader(a.PublicKey))
	if err != nil {
		return fmt.Errorf("error creating HashiCorp keyring: %s", err)
	}

View on GitHub (pinned to c9def3e214)

Solutions

  1. Re-download both SHA256SUMS and SHA256SUMS.sig fresh and retry; transient corruption is the most common cause.
  2. Confirm you are installing the official provider build from the HashiCorp/registry release, not a repackaged fork.
  3. Verify the bundled HashiCorp public key (72D7468F) matches the current well-known key at hashicorp.com/.well-known/pgp-key.txt; if HashiCorp rotated the signing key, upgrade Terraform to a version embedding the new key.
  4. Inspect TF_LOG=DEBUG output for the specific GPG error (it is logged before this sentinel is returned).
  5. If you legitimately mirror/re-sign internally, use a filesystem mirror with your own trust model rather than the registry path.
Defensive patterns

Strategy: try-catch

Validate before calling

// No caller pre-check; the Authenticator does the verification.
// Mitigate by re-downloading both .sig and sums from the canonical source first.

Type guard

func isNotSignedByHashiCorp(err error) bool {
    return errors.Is(err, releaseauth.ErrNotSignedByHashiCorp)
}

Try / catch

if err := sigAuth.Authenticate(); err != nil {
    if errors.Is(err, releaseauth.ErrNotSignedByHashiCorp) {
        // refuse to proceed; this is a potential supply-chain problem
        return errors.New("refusing to install: archive not signed by HashiCorp")
    }
    return err
}

Prevention

When it happens

Trigger: Returned at internal/releaseauth/signature.go:61 when openpgp.CheckDetachedSignature returns a non-nil err that is not openpgpErrors.ErrKeyExpired. The Authenticator is built by NewSignatureAuthentication(signature, signed) using the downloaded SHA256SUMS.sig and SHA256SUMS.

Common situations: A corrupted or truncated SHA256SUMS or .sig download. A signature produced by a non-HashiCorp key (unofficial/forked provider repackaged as official). A mismatch between sig and sums (e.g. sums from a different release). An attacker-in-the-middle modifying either file. A provider whose sums were re-signed after HashiCorp rotated keys (note: expired key is allowed, but a fully replaced key is not).

Understand the failure class

Related errors


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