{"record":{"id":"ba186383824407da","repo":"hyperledger/fabric","slug":"deliver-client-identity-expired-v-before","errorCode":null,"errorMessage":"deliver client identity expired %v before","messagePattern":"deliver client identity expired (.+?) before","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"common/deliver/acl.go","lineNumber":60,"sourceCode":"// SessionAccessControl holds access control related data for a common Envelope\n// that is used to determine if a request is allowed for the identity\n// associated with the request envelope.\ntype SessionAccessControl struct {\n\tsequencer          ConfigSequencer\n\tpolicyChecker      PolicyChecker\n\tchannelID          string\n\tenvelope           *common.Envelope\n\tlastConfigSequence uint64\n\tsessionEndTime     time.Time\n\tusedAtLeastOnce    bool\n}\n\n// Evaluate uses the PolicyChecker to determine if a request should be allowed.\n// The decision is cached until the identity expires or the chain configuration\n// changes.\nfunc (ac *SessionAccessControl) Evaluate() error {\n\tif !ac.sessionEndTime.IsZero() && time.Now().After(ac.sessionEndTime) {\n\t\treturn errors.Errorf(\"deliver client identity expired %v before\", time.Since(ac.sessionEndTime))\n\t}\n\n\tpolicyCheckNeeded := !ac.usedAtLeastOnce\n\n\tif currentConfigSequence := ac.sequencer.Sequence(); currentConfigSequence > ac.lastConfigSequence {\n\t\tac.lastConfigSequence = currentConfigSequence\n\t\tpolicyCheckNeeded = true\n\t}\n\n\tif !policyCheckNeeded {\n\t\treturn nil\n\t}\n\n\tac.usedAtLeastOnce = true\n\treturn ac.policyChecker.CheckPolicy(ac.envelope, ac.channelID)\n}\n","sourceCodeStart":42,"sourceCodeEnd":77,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/common/deliver/acl.go#L42-L77","documentation":"SessionAccessControl.Evaluate refuses deliver requests once the session end time has passed. The decision cache is invalidated at identity expiry, so requests after sessionEndTime are rejected with this error showing how long ago it expired.","triggerScenarios":"A deliver (block/filtered-block) request evaluated after time.Now() exceeds ac.sessionEndTime — the client identity's session window has closed.","commonSituations":"Long-running deliver streams outliving the client cert/session TTL; clock skew between peer and identity-issuing system; stale clients reconnecting after cert renewal.","solutions":["Renew the client certificate/identity and reconnect","Adjust the session end time/TTL configuration if it is too short for the workload","Synchronize clocks (NTP) between client and orderer/peer to avoid premature expiry"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if time.Now().After(sessionEndTime) {\n    return errors.New(\"deliver session expired, renew identity first\")\n}","typeGuard":null,"tryCatchPattern":"err := ac.Evaluate()\nif err != nil && strings.Contains(err.Error(), \"deliver client identity expired\") {\n    return renewIdentityAndReconnect() // refresh cert, reopen stream\n}","preventionTips":["Set client deliver-stream deadlines well under the identity session TTL","Renew certificates proactively before expiry","Synchronize clocks with NTP across client and server"],"tags":["auth","deliver","session-expiry","cert"],"backgroundTag":"identity-session-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"}