hyperledger/fabric · error
KeyMaterial not found in SigningIdentityInfo
Error message
KeyMaterial not found in SigningIdentityInfo
What it means
After loading the public key, the MSP looks up the private key in the BCCSP keystore by SKI. If not found, it falls back to importing the key from SigningIdentityInfo.PrivateSigner.KeyMaterial; when that field is also nil, this error is returned. Effectively: the private key matching the signing certificate is available nowhere.
Source
Thrown at msp/mspimpl.go:235
func (msp *bccspmsp) getSigningIdentityFromConf(sidInfo *m.SigningIdentityInfo) (SigningIdentity, error) {
if sidInfo == nil {
return nil, errors.New("getIdentityFromBytes error: nil sidInfo")
}
// Extract the public part of the identity
idPub, pubKey, err := msp.getIdentityFromConf(sidInfo.PublicSigner)
if err != nil {
return nil, err
}
// Find the matching private key in the BCCSP keystore
privKey, err := msp.bccsp.GetKey(pubKey.SKI())
// Less Secure: Attempt to import Private Key from KeyInfo, if BCCSP was not able to find the key
if err != nil {
mspLogger.Debugf("Could not find SKI [%s], trying KeyMaterial field: %+v\n", hex.EncodeToString(pubKey.SKI()), err)
if sidInfo.PrivateSigner == nil || sidInfo.PrivateSigner.KeyMaterial == nil {
return nil, errors.New("KeyMaterial not found in SigningIdentityInfo")
}
pemKey, _ := pem.Decode(sidInfo.PrivateSigner.KeyMaterial)
if pemKey == nil {
return nil, errors.Errorf("%s: wrong PEM encoding", sidInfo.PrivateSigner.KeyIdentifier)
}
privKey, err = msp.bccsp.KeyImport(pemKey.Bytes, &bccsp.ECDSAPrivateKeyImportOpts{Temporary: true})
if err != nil {
return nil, errors.WithMessage(err, "getIdentityFromBytes error: Failed to import EC private key")
}
}
// get the peer signer
peerSigner, err := signer.New(msp.bccsp, privKey)
if err != nil {
return nil, errors.WithMessage(err, "getIdentityFromBytes error: Failed initializing bccspCryptoSigner")
}
View on GitHub (pinned to 2736b63f8f)
Solutions
- Ensure keystore/ contains the private key matching signcerts (same SKI), or configure BCCSP to point at the keystore that has it
- Set PrivateSigner.KeyMaterial to the PEM-encoded private key when not relying on the keystore
- Verify SKI mismatch is not the issue — regenerate signcerts from the key if the cert was reissued
Example fix
// before
PrivateSigner: &m.KeyInfo{KeyIdentifier: ski} // KeyMaterial nil, not in keystore
// after
PrivateSigner: &m.KeyInfo{KeyIdentifier: ski, KeyMaterial: keyPEMBytes} Defensive patterns
Strategy: validation
Validate before calling
info := conf.SigningIdentity
if info.PrivateSigner == nil || len(info.PrivateSigner.KeyMaterial) == 0 {
// also confirm keystore has key matching cert SKI
if _, err := bccspInst.GetKey(pubSKI); err != nil {
return fmt.Errorf("private key neither in keystore nor KeyMaterial: %w", err)
}
} Type guard
func hasRecoverablePrivKey(info *m.SigningIdentityInfo) bool {
return info != nil && info.PrivateSigner != nil && len(info.PrivateSigner.KeyMaterial) > 0
} Try / catch
if err := msp.Setup(conf); err != nil && strings.Contains(err.Error(), "KeyMaterial not found") {
return fmt.Errorf("restore keystore key or embed KeyMaterial: %w", err)
} Prevention
- Never distribute MSP dirs without keystore/ (or provision an HSM-backed BCCSP consistently)
- Regenerate signcerts from the key whenever keys change to avoid SKI mismatch
- Keep BCCSP provider configuration identical across environments sharing MSP material
When it happens
Trigger: MSP setup where the keystore lacks a key with the signing cert's SKI and PrivateSigner.KeyMaterial is nil (KeyInfo present but empty, or PrivateSigner nil).
Common situations: keystore/ directory emptied or not copied; key stored in an HSM/other BCCSP provider than the one configured; MSP directory shared from a machine whose software keystore held the key.
Related errors
- Could not sign the ccpackage, err %s
- could not sign the proposal response payload
- could not serialize the signing identity: %v
- hash family not recognized [%s]
- %s: wrong PEM encoding
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/7a4c509ad7bdea17.
Report an issue: GitHub.