{"record":{"id":"5eb8e93fbf2eec3f","repo":"hyperledger/fabric","slug":"gossipping-peer-identity-expired","errorCode":null,"errorMessage":"gossipping peer identity expired","messagePattern":"gossipping peer identity expired","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gossip/identity/identity.go","lineNumber":136,"sourceCode":"\t}\n\n\tid := is.mcs.GetPKIidOfCert(identity)\n\tif !bytes.Equal(pkiID, id) {\n\t\treturn errors.New(\"identity doesn't match the computed pkiID\")\n\t}\n\n\tis.Lock()\n\tdefer is.Unlock()\n\t// Check if identity already exists.\n\t// If so, no need to overwrite it.\n\tif _, exists := is.pkiID2Cert[string(pkiID)]; exists {\n\t\treturn nil\n\t}\n\n\tvar expirationTimer *time.Timer\n\tif !expirationDate.IsZero() {\n\t\tif time.Now().After(expirationDate) {\n\t\t\treturn errors.New(\"gossipping peer identity expired\")\n\t\t}\n\t\t// Identity would be wiped out a millisecond after its expiration date\n\t\ttimeToLive := time.Until(expirationDate.Add(time.Millisecond))\n\t\texpirationTimer = time.AfterFunc(timeToLive, func() {\n\t\t\tis.delete(pkiID, identity)\n\t\t})\n\t}\n\n\tis.pkiID2Cert[string(id)] = newStoredIdentity(pkiID, identity, expirationTimer, is.sa.OrgByPeerIdentity(identity))\n\treturn nil\n}\n\n// get returns the identity of a given pkiID, or error if such an identity\n// isn't found\nfunc (is *identityMapperImpl) Get(pkiID common.PKIidType) (api.PeerIdentityType, error) {\n\tis.RLock()\n\tdefer is.RUnlock()\n\tstoredIdentity, exists := is.pkiID2Cert[string(pkiID)]","sourceCodeStart":118,"sourceCodeEnd":154,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/gossip/identity/identity.go#L118-L154","documentation":"identityMapperImpl.Put rejects an identity whose expiration date has already passed when it is being registered in the mapper's pkiID2Cert map. The gossip identity layer only stores identities that are still valid, since expired identities would immediately be purged by the expiration timer anyway. Callers (e.g. NewIdentityMapper during genesis/startup) must never feed already-expired certificates.","triggerScenarios":"Calling Put (directly or via NewIdentityMapper) with an api.PeerIdentityType whose configured expirationDate is non-zero and earlier than time.Now() — e.g. loading a snapshot/persisted identity store containing expired entries or passing an already-expired certificate at mapper creation.","commonSituations":"Peer restarted with a stale persistence directory after its TLS/identity certificate expired; clock skew between machines; restoring identity store from backup; tests fabricating identities with past expiration dates.","solutions":["Renew or replace the expired peer identity (MSP certificate) and its expiration date before starting the peer","Delete stale persisted identity data so Put is only called with valid identities","Verify system clocks (NTP) to rule out skew causing time.Now() to be past a still-valid expiration","If this is test code, generate identities with future expiration dates"],"exampleFix":"// before\nmapper.NewIdentityMapper(...).Put(pkiID, expiredIdentity)\n// after\nif !identityExpiration.IsZero() && time.Now().After(identityExpiration) {\n    // renew cert / skip entry\n}\nmapper.NewIdentityMapper(...).Put(pkiID, validIdentity)","handlingStrategy":"validation","validationCode":"func canPut(identity api.PeerIdentityType, expiration time.Time) bool {\n    return expiration.IsZero() || !time.Now().After(expiration)\n}\nif canPut(id, expirationDate) {\n    mapper.Put(pkiID, id)\n}","typeGuard":"func identityNotExpired(expiration time.Time) bool {\n    return expiration.IsZero() || time.Now().Before(expiration)\n}","tryCatchPattern":null,"preventionTips":["Renew peer MSP certificates before their expiration dates","Check persisted identity stores for expired entries at startup","Synchronize clocks with NTP across the network","In tests, always generate identities with future expirations"],"tags":["gossip","identity","certificate-expired"],"backgroundTag":"certificate-expired","analyzedSha":"2736b63f8fd5932511d56fe68b7039d15977f7f6","analyzedAt":"2026-09-04T08:52:36.465Z","contentChangedAt":"2026-09-04T08:52:36.465Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}