hashicorp/packer · error

signer and key must match when both are set

Error message

signer and key must match when both are set

What it means

Configure-time validation in signingBackendConfig: when both `signer` and `key` are set they must be identical strings. Setting both to different references is ambiguous, so the backend config is rejected.

Source

Thrown at post-processor/provenance/post-processor.go:382

	verifier, err := internalattestation.NewVerifier(ctx, backendConfig, signer)
	if err != nil {
		return nil, nil, err
	}

	return signer, verifier, nil
}

func (p *PostProcessor) signingBackendConfig() (internalattestation.BackendConfig, error) {
	mode := p.config.SigningMode
	if mode == "" {
		mode = internalattestation.SigningModeNone
	}

	signerRef := p.config.Signer
	if p.config.Key != "" {
		if signerRef != "" && signerRef != p.config.Key {
			return internalattestation.BackendConfig{}, fmt.Errorf("signer and key must match when both are set")
		}
		signerRef = p.config.Key
	}

	switch mode {
	case internalattestation.SigningModeNone:
		return internalattestation.BackendConfig{Mode: mode}, nil
	case internalattestation.SigningModeKey:
		if signerRef == "" {
			return internalattestation.BackendConfig{}, fmt.Errorf("signing_mode %q requires signer or key", mode)
		}
		return internalattestation.BackendConfig{
			Mode:        mode,
			SignerRef:   signerRef,
			VerifierRef: p.config.Verifier,
			Env:         p.currentEnv(),
		}, nil
	case internalattestation.SigningModeKMS:

View on GitHub (pinned to eb36e3c3e4)

Solutions

  1. Make signer and key exactly the same value.
  2. Remove the redundant `key` field and keep only `signer`.
  3. Or remove `signer` and keep only `key` (key takes precedence as signerRef).
  4. Re-run packer validate on the template before building.

Example fix

// before
"signer": "file:///keys/release.pem",
"key": "file:///keys/old.pem"
// after
"signer": "file:///keys/release.pem"
Defensive patterns

Strategy: validation

Validate before calling

import (
	"encoding/json"
	"fmt"
)
type provCfg struct {
	Signer string `json:"signer"`
	Key    string `json:"key"`
}
func checkSignerKeyMatch(raw json.RawMessage) error {
	var c provCfg
	if err := json.Unmarshal(raw, &c); err != nil { return err }
	if c.Signer != "" && c.Key != "" && c.Signer != c.Key {
		return fmt.Errorf("signer and key must match when both are set")
	}
	return nil
}

Try / catch

if err := p.Configure(raws); err != nil {
	if strings.Contains(err.Error(), "signer and key must match") {
		return fmt.Errorf("template error: unify signer/key: %w", err)
	}
	return err
}

Prevention

When it happens

Trigger: signingBackendConfig sees p.config.Signer non-empty and p.config.Key non-empty with signerRef != p.config.Key; raised during Configure or writeAttestation.

Common situations: User sets signer (e.g. file:///path/key.pem) and also an old `key` field left over from a template update with a different path; copy-paste of two example configs.

Related errors


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