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
- 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).
- 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.
- 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
- Validate BackendConfig fields (especially SignerRef) as soon as config is parsed, before the signer factory runs.
- Make the signer path a required config field with a clear error when the key signing mode is enabled without it.
- Add a startup self-test that constructs the Signer eagerly so missing config fails fast at load time, not at first signature.
- Document in the config schema which fields each signing mode requires.
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
- signing_mode %q does not support Sigstore bundle emission
- sign payload: %w
- attestation verification for signing_mode %q requires verifi
- attestation verification for signing_mode %q requires key or
- unable to determine attestation signing mode; set signing_mo
AI-assisted analysis of hashicorp/packer@eb36e3c3e4 (2026-09-05).
Data as JSON: /api/errors/2a4101bb161f9ed1.
Report an issue: GitHub.