hashicorp/terraform · error

authentication signature from unknown issuer

Error message

authentication signature from unknown issuer

What it means

From signatureAuthentication.findSigningKey after exhausting all keys. For every registry-supplied key, checkDetachedSignature returned ErrUnknownIssuer (this key did not produce the signature) or the key failed to decode; if no key validated, the package is treated as unsigned/tampered and verification fails terminally. The code comment notes unsigned packages are currently a hard authentication error.

Source

Thrown at internal/getproviders/package_authentication.go:563

		}

		// Any other signature error is terminal.
		if err != nil {
			return nil, "", fmt.Errorf("error checking signature: %s", err)
		}

		keyID := "n/a"
		if entity.PrimaryKey != nil {
			keyID = entity.PrimaryKey.KeyIdString()
		}

		log.Printf("[DEBUG] Provider signed by %s", entityString(entity))
		return &key, keyID, nil
	}

	// If none of the provided keys issued the signature, this package is
	// unsigned. This is currently a terminal authentication error.
	return nil, "", fmt.Errorf("authentication signature from unknown issuer")
}

// entityString extracts the key ID and identity name(s) from an openpgp.Entity
// for logging.
func entityString(entity *openpgp.Entity) string {
	if entity == nil {
		return ""
	}

	keyID := "n/a"
	if entity.PrimaryKey != nil {
		keyID = entity.PrimaryKey.KeyIdString()
	}

	var names []string
	for _, identity := range entity.Identities {
		names = append(names, identity.Name)
	}

View on GitHub (pinned to c9def3e214)

Solutions

  1. Re-download from the official registry to rule out mirror tampering; clear caches first.
  2. Confirm the provider version was published with a signing key and that the registry exposes that key for the version.
  3. Pin to a known-good provider release that is properly signed.
  4. If installing a genuinely unsigned community provider, use a source/configuration that does not require signature authentication (e.g. dev overrides) and accept the trust trade-off explicitly.

Example fix

// before: unsigned/tampered provider from a bad mirror
Error: authentication signature from unknown issuer
// after: install signed version from official registry
$ rm -rf .terraform/providers ~/.cache/terraform/plugin-cache/<provider>
$ terraform init   # against registry.terraform.io
Defensive patterns

Strategy: try-catch

Validate before calling

// Confirm at least one registry key could plausibly have signed the doc.
if len(keys) == 0 {
    return fmt.Errorf("registry returned no signing keys; cannot verify signature")
}

Try / catch

// Unsigned/unknown-issuer is terminal and security-relevant; never downgrade.
_, err := auth.AuthenticatePackage(loc)
if err != nil && strings.Contains(err.Error(), "unknown issuer") {
    return fmt.Errorf("provider package signature could not be verified against any registry key; refusing to install: %w", err)
}

Prevention

When it happens

Trigger: The loop at 533 finishes without returning; none of s.Keys could verify s.Signature over s.Document. Reachable when the package is unsigned, when the signature was made by a key absent from the registry response, or when the signature/document were altered so the issuer no longer matches any key.

Common situations: A mirror or proxy serves a tampered package/signature. A registry response that omitted the signing_keys for the version. A provider release where the signing key was not registered before publishing. Network MITM altering the signed document or signature. An unsigned community provider being installed from a source that requires signing.

Understand the failure class

Related errors


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