hyperledger/fabric · error
failed to parse private key: %v
Error message
failed to parse private key: %v
What it means
If the DER bytes are not PKCS#8 (or fail to parse), parsePrivateKey falls back to x509.ParseECPrivateKey to handle SEC1 EC keys generated by 'openssl ecparam'. When that also fails, this error wraps the underlying parse failure, meaning the key is neither valid PKCS#8 nor a SEC1 EC private key.
Source
Thrown at cmd/common/signer/signer.go:143
// Based on crypto/tls/tls.go but modified for Fabric:
func parsePrivateKey(der []byte) (crypto.PrivateKey, error) {
// OpenSSL 1.0.0 generates PKCS#8 keys.
if key, err := x509.ParsePKCS8PrivateKey(der); err == nil {
switch key := key.(type) {
// Fabric only supports ECDSA at the moment.
case *ecdsa.PrivateKey:
return key, nil
case ed25519.PrivateKey:
return key, nil
default:
return nil, errors.Errorf("found unknown private key type (%T) in PKCS#8 wrapping", key)
}
}
// OpenSSL ecparam generates SEC1 EC private keys for ECDSA.
key, err := x509.ParseECPrivateKey(der)
if err != nil {
return nil, errors.Errorf("failed to parse private key: %v", err)
}
return key, nil
}
func signECDSA(k *ecdsa.PrivateKey, digest []byte) (signature []byte, err error) {
r, s, err := ecdsa.Sign(rand.Reader, k, digest)
if err != nil {
return nil, err
}
s, err = utils.ToLowS(&k.PublicKey, s)
if err != nil {
return nil, err
}
return marshalECDSASignature(r, s)
}View on GitHub (pinned to 2736b63f8f)
Solutions
- Decrypt the key first: openssl pkey -in key.pem -passin pass:... -out key_nocrypt.pem
- Convert to supported format: openssl ecparam/openssl pkey to produce an unencrypted EC PEM key
- Check the PEM header — 'ENCRYPTED PRIVATE KEY' or 'RSA PRIVATE KEY' indicates the unsupported case
- Re-export the key from the MSP/cert-authority source and confirm with openssl pkey -noout -text
Example fix
// before: encrypted key -----BEGIN ENCRYPTED PRIVATE KEY----- // after openssl pkcs8 -topk8 -nocrypt -in key.pem -out key_nocrypt.pem # or: openssl pkey -in enc.pem -passin pass:secret -out key.pem
Defensive patterns
Strategy: validation
Validate before calling
b, _ := os.ReadFile(keyPath)
blk, _ := pem.Decode(b)
if strings.Contains(blk.Headers["Proc-Type"], "ENCRYPTED") || blk.Type == "ENCRYPTED PRIVATE KEY" {
return fmt.Errorf("%s is encrypted; decrypt before use", keyPath)
}
if _, err := x509.ParseECPrivateKey(blk.Bytes); err != nil {
if _, err8 := x509.ParsePKCS8PrivateKey(blk.Bytes); err8 != nil {
return fmt.Errorf("%s is neither PKCS#8 nor SEC1 EC key", keyPath)
}
} Try / catch
s, err := signer.NewSigner(keyPath, idPath)
if err != nil {
if strings.Contains(err.Error(), "failed to parse private key") {
return fmt.Errorf("key %s unparseable; decrypt/convert with openssl pkey", keyPath)
}
return err
} Prevention
- Never deploy passphrase-protected keys without decrypting them
- Convert all keys to unencrypted PKCS#8 ECDSA PEM in provisioning scripts
- Verify with openssl pkey -in key.pem -noout before use
When it happens
Trigger: Key file contains an encrypted PEM block (passphrase-protected, pem.Decode yields the block but DER is encrypted), an RSA/PKCS#1 key that failed PKCS#8 parse, corrupted DER, or a public key instead of a private key.
Common situations: Passphrase-protected key with no decryption step; PKCS#1 RSA key ('BEGIN RSA PRIVATE KEY') rejected by both parsers; truncated or edited key file; copied key missing lines.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- found unknown private key type (%T) in PKCS#8 wrapping
- found unknown private key type (%T) in msg signing
- failed to decode PEM block from %s
- Unknown hashing algorithm type: %s
- Internal error, BCCSP could not be initialized : %s
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/216fe8e4490eb711.
Report an issue: GitHub.