hashicorp/terraform · error

error decoding trust signature

Error message

error decoding trust signature: %s

What it means

Thrown by signatureAuthentication.AuthenticatePackage when openpgpArmor.Decode fails to parse signingKey.TrustSignature as ASCII-armored OpenPGP data. This runs inside the partner-verification branch (signingKey.TrustSignature != ''), immediately after successfully decoding the signing key itself. The trust_signature is a signature by the registry operator (HashiCorp Partners key) over the author key; if its armor is malformed, partner verification aborts at package_authentication.go:442-444.

Solutions

  1. Have the registry populate trust_signature with a complete, valid ASCII-armored OpenPGP signature (full BEGIN/END PGP SIGNATURE block).
  2. If the provider should not be a partner, leave trust_signature empty rather than set to invalid data.
  3. Validate trust_signature with gpg --list-packets or openpgpArmor.Decode before publishing.
  4. Inspect the registry JSON to confirm trust_signature is not truncated or escaped incorrectly.
Defensive patterns

Strategy: validation

Validate before calling

func validTrustSignatureArmor(k getproviders.SigningKey) error {
    if k.TrustSignature == "" {
        return nil
    }
    if _, err := openpgpArmor.Decode(strings.NewReader(k.TrustSignature)); err != nil {
        return fmt.Errorf("invalid trust_signature armor: %w", err)
    }
    return nil
}

Try / catch

_, err := auth.AuthenticatePackage(loc)
if err != nil && strings.Contains(err.Error(), "error decoding trust signature") {
    // registry served a malformed trust signature; re-fetch key metadata and retry
    return err
}

Prevention

When it happens

Trigger: A provider whose signing key has a non-empty trust_signature whose value is not valid armored OpenPGP — bad armor header, truncated base64, or the wrong field value placed into trust_signature by the registry.

Common situations: A registry bug placing the key body or a binary signature into trust_signature instead of the armored trust signature; a copy-paste/truncation when configuring a private registry's signing metadata; a proxy mangling the JSON field.

Related errors


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

Appendix: source

Thrown at internal/getproviders/package_authentication.go:444

		return &PackageAuthenticationResult{result: officialProvider, KeyID: keyID}, nil
	}

	// If the signing key has a trust signature, attempt to verify it with the
	// HashiCorp partners public key.
	if signingKey.TrustSignature != "" {
		hashicorpPartnersKeyring, err := openpgp.ReadArmoredKeyRing(strings.NewReader(HashicorpPartnersKey))
		if err != nil {
			return nil, fmt.Errorf("error creating HashiCorp Partners keyring: %s", err)
		}

		authorKey, err := openpgpArmor.Decode(strings.NewReader(signingKey.ASCIIArmor))
		if err != nil {
			return nil, fmt.Errorf("error decoding signing key: %s", err)
		}

		trustSignature, err := openpgpArmor.Decode(strings.NewReader(signingKey.TrustSignature))
		if err != nil {
			return nil, fmt.Errorf("error decoding trust signature: %s", err)
		}

		_, err = s.checkDetachedSignature(hashicorpPartnersKeyring, authorKey.Body, trustSignature.Body, nil)
		if err != nil {
			return nil, fmt.Errorf("error verifying trust signature: %s", err)
		}

		return &PackageAuthenticationResult{result: partnerProvider, KeyID: keyID}, nil
	}

	// We have a valid signature, but it's not from the HashiCorp key, and it
	// also isn't a trusted partner. This is a community provider.
	return &PackageAuthenticationResult{result: communityProvider, KeyID: keyID}, nil
}

func (s signatureAuthentication) checkDetachedSignature(keyring openpgp.KeyRing, signed, signature io.Reader, config *packet.Config) (*openpgp.Entity, error) {
	entity, err := openpgp.CheckDetachedSignature(keyring, signed, signature, config)
	// FIXME: it's not clear what should be done with provider signing key

View on GitHub (pinned to d32a084675)