hashicorp/packer · error

signing_mode %q requires signer

Error message

signing_mode %q requires signer

What it means

The PEM signing backend in internal/attestation/sign_key.go constructs its signer via newPEMSigner, which requires a BackendConfig.SignerRef pointing at a PEM-encoded private key file. When the 'key' signing mode is selected but no signer reference is supplied, the constructor immediately fails with this error. It is a configuration validation guard, thrown before any file I/O or key parsing occurs, so it always indicates a missing 'signer' setting rather than a bad key file.

Source

Thrown at internal/attestation/sign_key.go:37

)

func init() {
	RegisterSigner(SigningModeKey, newPEMSigner)
}

type pemSigner struct {
	signer   crypto.Signer
	verifier *pemVerifier
}

type pemVerifier struct {
	publicKey crypto.PublicKey
	keyID     string
}

func newPEMSigner(_ context.Context, cfg BackendConfig) (Signer, error) {
	if cfg.SignerRef == "" {
		return nil, fmt.Errorf("signing_mode %q requires signer", SigningModeKey)
	}

	signer, verifier, err := loadPEMSigner(cfg.SignerRef)
	if err != nil {
		return nil, err
	}

	return &pemSigner{signer: signer, verifier: verifier}, nil
}

func (s *pemSigner) Sign(_ context.Context, payloadType string, payload []byte) (Signature, error) {
	pae := PreAuthEncode(payloadType, payload)

	var message []byte
	var opts crypto.SignerOpts
	if _, ok := s.signer.Public().(ed25519.PublicKey); ok {
		message = pae
		opts = crypto.Hash(0)

View on GitHub (pinned to eb36e3c3e4)

Solutions

  1. Set the signer reference in your configuration: point cfg.SignerRef at a PEM file containing an RSA, ECDSA, or PKCS#8 private key (the same value used by loadPEMSigner to os.ReadFile the key).
  2. Check the config-loading code path (flags, env vars, config file) that builds BackendConfig and confirm the signer option is actually parsed and assigned to SignerRef.
  3. If signing is not intended, disable or unset the key signing mode so newPEMSigner is never invoked instead of leaving the mode enabled with no signer.

Example fix

// before: enabling key signing without a signer
attestation.SigningMode = "key"
// signer path never provided -> error

// after: supply the signer PEM path
attestation.SigningMode = "key"
attestation.SignerRef = "/etc/packer/attest-signer.pem" // RSA/ECDSA/PKCS#8 private key
Defensive patterns

Strategy: validation

Validate before calling

if cfg.SignerRef == "" {
	return fmt.Errorf("key signing mode requires a signer: set the signer PEM path before enabling signing mode %q", attestation.SigningModeKey)
}
if _, err := os.Stat(cfg.SignerRef); err != nil {
	return fmt.Errorf("signer %q unavailable: %w", cfg.SignerRef, err)
}

Prevention

When it happens

Trigger: Calling code registers/enables signing mode SigningModeKey ("key") and invokes the signer factory newPEMSigner with a BackendConfig whose SignerRef field is the empty string — i.e. the signer path was never set.

Common situations: Users enable key-based attestation signing in a config file or flags but omit the signer/private-key path option; environment-driven config leaves the signer variable empty; a refactor renamed the config field so the value no longer populates SignerRef; code paths that programmatically build BackendConfig forget to assign SignerRef.

Related errors


AI-assisted analysis of hashicorp/packer@eb36e3c3e4 (2026-09-05). Data as JSON: /api/errors/2a4101bb161f9ed1. Report an issue: GitHub.