hyperledger/fabric · error
PKIID wasn't found
Error message
PKIID wasn't found
What it means
identityMapperImpl.Get looks up a peer identity by PKI-ID in pkiID2Cert and returns this error when no identity has been stored under that key. It is thrown by Get (called from Verify), meaning the code attempted to verify a message signed by a peer whose identity was never registered (or was already evicted by the expiration timer).
Source
Thrown at gossip/identity/identity.go:156
// Identity would be wiped out a millisecond after its expiration date
timeToLive := time.Until(expirationDate.Add(time.Millisecond))
expirationTimer = time.AfterFunc(timeToLive, func() {
is.delete(pkiID, identity)
})
}
is.pkiID2Cert[string(id)] = newStoredIdentity(pkiID, identity, expirationTimer, is.sa.OrgByPeerIdentity(identity))
return nil
}
// get returns the identity of a given pkiID, or error if such an identity
// isn't found
func (is *identityMapperImpl) Get(pkiID common.PKIidType) (api.PeerIdentityType, error) {
is.RLock()
defer is.RUnlock()
storedIdentity, exists := is.pkiID2Cert[string(pkiID)]
if !exists {
return nil, errors.New("PKIID wasn't found")
}
return storedIdentity.fetchIdentity(), nil
}
// Sign signs a message, returns a signed message on success
// or an error on failure
func (is *identityMapperImpl) Sign(msg []byte) ([]byte, error) {
return is.mcs.Sign(msg)
}
func (is *identityMapperImpl) Stop() {
is.once.Do(func() {
close(is.stopChan)
})
}
// Verify verifies a signed message
func (is *identityMapperImpl) Verify(vkID, signature, message []byte) error {View on GitHub (pinned to 2736b63f8f)
Solutions
- Ensure the peer's identity is registered via Put before verifying messages from it
- Wait for / trigger gossip identity pull so the unknown peer's cert is disseminated
- Check expiration timers — if entries vanish too early, review expirationDate values and clock sync
- Filter or re-fetch messages from peers that are not in the mapper instead of verifying blindly
Example fix
// before
if err := mapper.Verify(pkiID, sig, msg); err != nil { return err }
// after
if _, err := mapper.Get(pkiID); err != nil {
// identity unknown: pull identity first or ignore message
return nil // or trigger identity pull
}
return mapper.Verify(pkiID, sig, msg) Defensive patterns
Strategy: try-catch
Validate before calling
if _, err := mapper.Get(pkiID); err != nil {
// identity unknown — pull disseminated identity before verifying
} Try / catch
_, err := mapper.Get(pkiID)
if err != nil && err.Error() == "PKIID wasn't found" {
// request identity via gossip identity pull, or skip message
return ErrUnknownPeer
}
if err := mapper.Verify(pkiID, signature, msg); err != nil {
return err
}
return nil Prevention
- Ensure gossip identity dissemination completes before processing peer messages
- Monitor for entries disappearing early — review expirationDate values and timers
- Persist/restore identity mapper contents across peer restarts
- Ignore (don't fail hard on) messages from unregistered peers
When it happens
Trigger: Calling Verify (or Get) with a pkiID that was never passed to Put, or whose identity expired and was deleted by the time.AfterFunc expiration timer, or after a purge.
Common situations: Gossip message arrives from an unknown/removed peer; identity expiry timer deleted the entry before verification; channel membership changed; persisted identity store was cleared; peer joined before identity dissemination completed.
Related errors
- PKIID is nil
- identity is nil
- identity doesn't match the computed pkiID
- gossipping peer identity expired
- failed unmarshaling identity %s
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/31a5ba0b126f1f26.
Report an issue: GitHub.