hashicorp/packer · error
private key does not implement crypto.Signer
Error message
private key does not implement crypto.Signer
What it means
In loadPEMPrivateKeyAsPublic, the PEM block parsed as a PKCS#8 private key, but the resulting value does not implement crypto.Signer, so a corresponding public verifier cannot be derived (deriving the public key requires calling Signer.Public()). The load is aborted. This mirrors error 104 but on the verifier-extraction path.
Source
Thrown at internal/attestation/sign_key.go:203
if privateKey, verifier, err := loadPEMPrivateKeyAsPublic(contents); err == nil {
return privateKey, verifier, nil
}
return nil, nil, fmt.Errorf("unsupported PEM verifier data")
}
func loadPEMPrivateKeyAsPublic(contents []byte) (crypto.PublicKey, []byte, error) {
block, _ := pem.Decode(contents)
if block == nil {
return nil, nil, fmt.Errorf("no PEM block found")
}
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("private key does not implement crypto.Signer")
}
} 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 data")
}
publicKeyPEM, err := marshalPublicKeyPEM(signer.Public())
if err != nil {
return nil, nil, err
}
publicKey, _, err := loadPEMPublicKey(publicKeyPEM)
if err != nil {
return nil, nil, err
}View on GitHub (pinned to eb36e3c3e4)
Solutions
- Provide the public key or certificate directly instead of deriving it from an exotic private key: 'openssl pkey -pubout -out verifier.pem'.
- Regenerate with a standard signing algorithm (RSA, ECDSA, Ed25519) and export as PKCS#8 PEM.
- Test-parse the block with x509.ParsePKCS8PrivateKey and type-assert crypto.Signer to see the concrete key type Go produced.
- If the key must stay in an HSM, use the HSM's crypto.Signer implementation rather than a PEM file.
Example fix
// before
v, err := attestation.LoadPEMVerifier("kem-private.pem") // private key does not implement crypto.Signer
// after
$ openssl pkey -in signing-key.pem -pubout -out verifier.pem
v, err := attestation.LoadPEMVerifier("verifier.pem") Defensive patterns
Strategy: validation
Validate before calling
raw, _ := os.ReadFile(path)
block, _ := pem.Decode(raw)
if block == nil {
return fmt.Errorf("%s: no PEM block", path)
}
key, err := x509.ParsePKCS8PrivateKey(block.Bytes)
if err == nil {
if _, ok := key.(crypto.Signer); !ok {
return fmt.Errorf("%s: PKCS#8 key type %T is not a signer; supply the public key/cert instead", path, key)
}
}
return nil Type guard
func implementsCryptoSigner(key any) bool {
s, ok := key.(crypto.Signer)
return ok && s != nil
} Try / catch
v, err := attestation.LoadPEMVerifier(path)
if err != nil && strings.Contains(err.Error(), "does not implement crypto.Signer") {
return fmt.Errorf("%s wraps a non-signing private key; provide a PUBLIC KEY or CERTIFICATE file directly", path)
} Prevention
- Prefer distributing public keys or certificates to verifiers rather than deriving them from private keys.
- Regenerate exotic PKCS#8 blobs with standard RSA/EC/Ed25519 keys when private-key input is required.
- Type-assert crypto.Signer on parsed keys in preflight checks to fail early with a clear message.
- Keep signing and verification key material in separate, clearly named files to avoid cross-use.
When it happens
Trigger: Calling LoadPEMVerifier/LoadPEMVerifierBytes on a PKCS#8 PEM whose parsed key is not a crypto.Signer (non-signing key types wrapped in PKCS#8, unusual algorithm OIDs).
Common situations: Reusing a key-encapsulation or key-agreement PKCS#8 blob as an attestation verifier; HSM-exported blobs with opaque algorithm identifiers; keys generated with tooling that emits non-standard PKCS#8 payloads.
Related errors
- signer %q does not implement crypto.Signer
- signing_mode %q does not support Sigstore bundle emission
- decode envelope payload: %w
- decode envelope signature: %w
- sign payload: %w
AI-assisted analysis of hashicorp/packer@eb36e3c3e4 (2026-09-05).
Data as JSON: /api/errors/a2da079dedbb7ead.
Report an issue: GitHub.