hyperledger/fabric · error
identity doesn't match the computed pkiID
Error message
identity doesn't match the computed pkiID
What it means
After classification and validation succeed, Put recomputes the PKI-ID from the certificate via mcs.GetPKIidOfCert and requires it to byte-equal the supplied pkiID. A mismatch means the caller associated an identity with the wrong PKI-ID — a integrity check protecting the identity store against spoofed key/identity pairs.
Source
Thrown at gossip/identity/identity.go:122
if pkiID == nil {
return errors.New("PKIID is nil")
}
if identity == nil {
return errors.New("identity is nil")
}
expirationDate, err := is.mcs.Expiration(identity)
if err != nil {
return errors.Wrap(err, "failed classifying identity")
}
if err := is.mcs.ValidateIdentity(identity); err != nil {
return err
}
id := is.mcs.GetPKIidOfCert(identity)
if !bytes.Equal(pkiID, id) {
return errors.New("identity doesn't match the computed pkiID")
}
is.Lock()
defer is.Unlock()
// Check if identity already exists.
// If so, no need to overwrite it.
if _, exists := is.pkiID2Cert[string(pkiID)]; exists {
return nil
}
var expirationTimer *time.Timer
if !expirationDate.IsZero() {
if time.Now().After(expirationDate) {
return errors.New("gossipping peer identity expired")
}
// Identity would be wiped out a millisecond after its expiration date
timeToLive := time.Until(expirationDate.Add(time.Millisecond))
expirationTimer = time.AfterFunc(timeToLive, func() {View on GitHub (pinned to 2736b63f8f)
Solutions
- Always derive pkiID via mcs.GetPKIidOfCert(identity) for the exact identity being registered instead of trusting caller-supplied values
- Verify the peer's identity source (message fields) isn't mixing identities from different peers
- Check for version skew in crypto libraries that changes PKI-ID derivation between components
Example fix
// before err := mapper.Put(msg.PkiId, identity) // pkiID taken from message // after pkiID := mapper.GetPKIidOfCert(identity) // via mcs err := mapper.Put(pkiID, identity)
Defensive patterns
Strategy: validation
Validate before calling
computed := mcs.GetPKIidOfCert(identity)
if !bytes.Equal(computed, pkiID) {
return errors.New("refusing to put: identity/pkiID mismatch")
}
err := mapper.Put(pkiID, identity) Type guard
func pkiIDMatches(mcs api.MessageCryptoService, pkiID common.PKIidType, id api.PeerIdentityType) bool {
return bytes.Equal(pkiID, mcs.GetPKIidOfCert(id))
} Try / catch
if err := mapper.Put(pkiID, identity); err != nil && strings.Contains(err.Error(), "doesn't match the computed pkiID") {
logger.Warning("identity/pkiID mismatch — possible tampering or stale identity")
return
} Prevention
- Always derive pkiID via mcs.GetPKIidOfCert(identity) for the same identity you register
- Never trust pki-id fields from messages without recomputing them
- Watch for crypto library/Fabric version skew affecting PKI-ID derivation
- Treat mismatch errors as security signals, not transient failures
When it happens
Trigger: Calling Put with a (pkiID, identity) pair where pkiID was taken from a different peer's message, hand-crafted, or computed with a different hash/cert than the one in identity.
Common situations: Manually wiring identities in tests; processing tampered or mis-routed gossip messages; PKI-ID derivation changes after a Fabric/crypto library upgrade.
Related errors
- PKIID is nil
- identity is nil
- failed classifying identity
- failed unmarshaling identity %s
- Could not serialize the signing identity: %s
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/db8871a5b9932e21.
Report an issue: GitHub.