hashicorp/terraform · critical · ErrNotSignedByHashiCorp

failed to authenticate that the archive was signed by HashiC

Error message

failed to authenticate that the archive was signed by HashiCorp

What it means

ErrNotSignedByHashiCorp is returned by SignatureAuthentication.Authenticate when OpenPGP detached-signature verification of the SHA256SUMS file against the HashiCorp public key fails for any reason other than an expired key (which is tolerated and logged at WARN). It means the archive's signature cannot be attributed to HashiCorp, so the release is not authenticated as official.

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 d32a084675)

Solutions

  1. Re-download both the SHA256SUMS and SHA256SUMS.sig files from the official source and retry.
  2. Verify the public key in use is the official HashiCorp key (ID 72D7468F) — do not override PublicKey except in controlled tests.
  3. If the release genuinely is not signed by HashiCorp (community/third-party plugin), do not use SignatureAuthentication; rely on the appropriate trust mechanism for that source.
  4. Check the [DEBUG] GPG log line for the underlying OpenPGP error to distinguish a bad signature from a bad key.

Example fix

// before
auth := releaseauth.NewSignatureAuthentication(sigBytes, sumsBytes)
if err := auth.Authenticate(); err != nil {
    return err
}

// after — ensure fresh, complete downloads and the official key
if !bytes.Equal(auth.PublicKey, releaseauth.HashiCorpPublicKey) {
    return errors.New("refusing to verify with a non-HashiCorp key")
}
if err := auth.Authenticate(); err != nil {
    return fmt.Errorf("release is NOT signed by HashiCorp; do not trust this archive: %w", err)
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Ensure the official key is in use and inputs are non-empty
if len(signature) == 0 || len(signed) == 0 {
    return errors.New("missing signature or SHA256SUMS data")
}

Type guard

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

Try / catch

err := releaseauth.NewSignatureAuthentication(sig, sums).Authenticate()
if errors.Is(err, releaseauth.ErrNotSignedByHashiCorp) {
    // do NOT proceed; re-download official artifacts and retry once
    return redownloadAndVerify()
}

Prevention

When it happens

Trigger: SignatureAuthentication.Authenticate at signature.go:52 calls openpgp.CheckDetachedSignature; if the resulting error is non-nil and not openpgpErrors.ErrKeyExpired, it returns ErrNotSignedByHashiCorp (signature.go:59-61).

Common situations: Tampered or rebuilt SHA256SUMS / .sig pair; signature made with a different (non-HashiCorp) key; corrupted .sig download; wrong public key configured (e.g. tests overriding PublicKey); third-party mirror re-signing releases.

Understand the failure class

Related errors


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