hashicorp/terraform · error

error decoding signing key

Error message

error decoding signing key: %s

What it means

Thrown by signatureAuthentication.AuthenticatePackage when openpgpArmor.Decode fails to parse signingKey.ASCIIArmor (the registry-provided signing key) as OpenPGP ASCII-armored data. This branch runs only when the signing key carries a TrustSignature and the partners keyring was built. The registry returns the ASCII-armored public key of the signing identity; malformed armor (bad header, truncated, not actually armored) is rejected at package_authentication.go:437-439.

Solutions

  1. Have the registry serve a complete, valid ASCII-armored OpenPGP public key in the signing key's ascii_armor (full '-----BEGIN PGP PUBLIC KEY BLOCK-----' ... '-----END PGP PUBLIC KEY BLOCK-----').
  2. Validate the key with gpg --dearmor or openpgpArmor.Decode before publishing to the registry.
  3. If the key was exported in binary, re-export with --armor.
  4. Check the registry JSON response for truncation or escaping issues around ascii_armor.
Defensive patterns

Strategy: validation

Validate before calling

// Validate a registry-returned signing key's armor parses before trusting it.
func validSigningKeyArmor(k getproviders.SigningKey) error {
    if k.TrustSignature == "" {
        return nil // branch not reached; nothing to validate
    }
    if _, err := openpgpArmor.Decode(strings.NewReader(k.ASCIIArmor)); err != nil {
        return fmt.Errorf("invalid signing key ascii_armor: %w", err)
    }
    return nil
}

Try / catch

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

Prevention

When it happens

Trigger: A provider whose signing key has a non-empty trust_signature, where the ASCIIArmor field is not valid armored OpenPGP — bad BEGIN PGP block, missing checksum, base64 corruption, or the wrong content pasted into ascii_armor by a registry.

Common situations: A custom/private registry serving a signing key whose ascii_armor was copy-pasted incompletely or includes the wrapping header twice; a registry bug serializing the key; a proxy mangling the JSON/key payload; a key exported in binary instead of armored form.

Related errors


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

Appendix: source

Thrown at internal/getproviders/package_authentication.go:439

	if err != nil {
		return nil, fmt.Errorf("error creating HashiCorp keyring: %s", err)
	}
	_, err = s.checkDetachedSignature(hashicorpKeyring, bytes.NewReader(s.Document), bytes.NewReader(s.Signature), nil)
	if err == nil {
		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

View on GitHub (pinned to d32a084675)