hashicorp/packer · error
signer %q does not implement crypto.Signer
Error message
signer %q does not implement crypto.Signer
What it means
The PEM block parsed successfully as a PKCS#8 private key, but the resulting Go value does not implement crypto.Signer, so it cannot be used to sign attestations. loadPEMSigner rejects it rather than returning a signer that cannot Sign(). This typically means the PKCS#8 payload wraps a key type the signer path cannot use.
Source
Thrown at internal/attestation/sign_key.go:150
}
func loadPEMSigner(path string) (crypto.Signer, *pemVerifier, error) {
contents, err := os.ReadFile(path)
if err != nil {
return nil, nil, fmt.Errorf("read signer %q: %w", path, err)
}
block, _ := pem.Decode(contents)
if block == nil {
return nil, nil, fmt.Errorf("decode signer %q: no PEM block found", path)
}
var signer crypto.Signer
if key, err := x509.ParsePKCS8PrivateKey(block.Bytes); err == nil {
var ok bool
signer, ok = key.(crypto.Signer)
if !ok {
return nil, nil, fmt.Errorf("signer %q does not implement crypto.Signer", path)
}
} else if key, err := x509.ParsePKCS1PrivateKey(block.Bytes); err == nil {
signer = key
} else if key, err := x509.ParseECPrivateKey(block.Bytes); err == nil {
signer = key
} else {
return nil, nil, fmt.Errorf("unsupported private key in signer %q", path)
}
publicKeyPEM, err := marshalPublicKeyPEM(signer.Public())
if err != nil {
return nil, nil, err
}
verifier, err := LoadPEMVerifierBytes(publicKeyPEM)
if err != nil {
return nil, nil, err
}View on GitHub (pinned to eb36e3c3e4)
Solutions
- Regenerate a standard signing key: 'openssl genpkey -algorithm ED25519' or '-algorithm RSA' / 'EC', then export as PKCS#8 PEM.
- Re-export the key so the PKCS#8 payload contains a normal RSA/EC/Ed25519 private key.
- Confirm what Go parsed by running x509.ParsePKCS8PrivateKey on the block bytes in a small test and printing the concrete type.
- If the key lives in an HSM, use a crypto.Signer handle (PKCS#11) rather than a PEM file, or export a software signing key.
Example fix
// before
$ openssl genpkey -algorithm <non-signing KEM> -out signer.pem
signer, _, err := attestation.NewSigner("signer.pem") // does not implement crypto.Signer
// after
$ openssl genpkey -algorithm ED25519 -out signer.pem
signer, _, err := attestation.NewSigner("signer.pem") // ok Defensive patterns
Strategy: validation
Validate before calling
raw, _ := os.ReadFile(keyPath)
block, _ := pem.Decode(raw)
if block == nil {
return fmt.Errorf("%s: no PEM block", keyPath)
}
key, err := x509.ParsePKCS8PrivateKey(block.Bytes)
if err != nil {
return err // falls through to PKCS1/EC handling in the library
}
if _, ok := key.(crypto.Signer); !ok {
return fmt.Errorf("%s: PKCS#8 key type %T cannot sign; regenerate with RSA/EC/Ed25519", keyPath, key)
} Type guard
func isCryptoSigner(key any) bool {
_, ok := key.(crypto.Signer)
return ok
} Try / catch
signer, verifier, err := attestation.NewSigner(keyPath)
if err != nil && strings.Contains(err.Error(), "does not implement crypto.Signer") {
return fmt.Errorf("%s holds a non-signing key; regenerate: openssl genpkey -algorithm ED25519 -out %s", keyPath, keyPath)
} Prevention
- Generate signing keys only with standard algorithms: RSA, ECDSA, or Ed25519.
- Avoid keys exported from HSMs/PKCS#12 with non-signing algorithm identifiers; use a real crypto.Signer integration instead.
- Pre-check parsed key types in a smoke test before production signing.
- Keep tool-generated key material and its intended use documented to prevent mismatches.
When it happens
Trigger: Calling newPEMSigner(path) where the file holds a PKCS#8 structure whose parsed key is not a crypto.Signer (e.g. certain PKCS#8-wrapped key agreement/key encapsulation payloads, or unusual key types like ed25519ph containers depending on the Go version).
Common situations: Key exported from an HSM or PKCS#12 bundle with an unusual algorithm identifier; a key generated for encryption-only use; mismatch between the declared OID in the PKCS#8 blob and an actual signing key.
Related errors
- private key does not implement crypto.Signer
- signing_mode %q does not support Sigstore bundle emission
- sign payload: %w
- read signer %q: %w
- decode signer %q: no PEM block found
AI-assisted analysis of hashicorp/packer@eb36e3c3e4 (2026-09-05).
Data as JSON: /api/errors/0dcd477b8b30f387.
Report an issue: GitHub.