hyperledger/fabric · error
client identity expired
Error message
client identity expired
What it means
checkACL extracts the creator from the SignatureHeader and checks its certificate's expiration via crypto.ExpiresAt. If the identity has an expiration timestamp and that time is in the past, the request is rejected with 'client identity expired' before the ACL policy is evaluated.
Source
Thrown at core/ledger/snapshotgrpc/snapshot_service.go:117
return nil, err
}
result, err := lgr.PendingSnapshotRequests()
if err != nil {
return nil, err
}
return &pb.QueryPendingSnapshotsResponse{BlockNumbers: result}, nil
}
func (s *SnapshotService) checkACL(resName string, signatureHdr *cb.SignatureHeader, signedRequest *pb.SignedSnapshotRequest) error {
if signatureHdr == nil {
return errors.New("missing signature header")
}
expirationTime := crypto.ExpiresAt(signatureHdr.Creator)
if !expirationTime.IsZero() && time.Now().After(expirationTime) {
return errors.New("client identity expired")
}
if err := s.ACLProvider.CheckACLNoChannel(
resName,
[]*protoutil.SignedData{{
Identity: signatureHdr.Creator,
Data: signedRequest.Request,
Signature: signedRequest.Signature,
}},
); err != nil {
return err
}
return nil
}
func (s *SnapshotService) getLedger(channelID string) (ledger.PeerLedger, error) {
if channelID == "" {View on GitHub (pinned to 2736b63f8f)
Solutions
- Renew the client's enrollment certificate from the CA (fabric-ca enroll again) and rebuild the request.
- Verify node clock skew — a badly skewed clock can flag a valid cert as expired.
- Update MSP/certificates across the network per the Fabric operational guide after CA rotation.
- Re-sign the request with the fresh identity rather than reusing cached signed payloads.
Example fix
// before
signer := loadSigner("expired-cert.pem")
// after
signer := loadSigner("renewed-cert.pem") // re-enrolled via fabric-ca; check crypto.ExpiresAt(hdr.Creator) Defensive patterns
Strategy: validation
Validate before calling
hdr := req.GetSignatureHeader()
if hdr != nil {
if exp := crypto.ExpiresAt(hdr.Creator); !exp.IsZero() && time.Now().After(exp) {
return fmt.Errorf("identity expired at %s; re-enroll before submitting", exp)
}
} Type guard
func identityValid(hdr *cb.SignatureHeader) bool {
exp := crypto.ExpiresAt(hdr.GetCreator())
return exp.IsZero() || time.Now().Before(exp)
} Try / catch
_, err := svc.Generate(ctx, signedReq)
if err != nil && strings.Contains(err.Error(), "client identity expired") {
return reenrollAndRetry(ctx, signedReq) // fabric-ca re-enroll, rebuild & re-sign request
}
return err Prevention
- Monitor certificate expiry (Fabric default ~1 year) and rotate before deadlines.
- After CA renewal, re-enroll all clients and update MSPs network-wide.
- Keep clocks synced via NTP to avoid false expiry detection.
- Never replay long-cached signed requests across cert rotations.
When it happens
Trigger: Any snapshot request (Generate/Cancel/QueryPendings) signed by an identity whose x509 certificate expiry has passed, or a header whose Creator cert carries an expired/notAfter field.
Common situations: Long-running clients whose enrollment certificates expired (Fabric default 1-year certs); peers/clients not rotated after CA certificate renewal; offline signatures assembled long ago and replayed after expiry.
Related errors
- missing signature header
- failed to unmarshal snapshot request
- missing channel ID
- cannot find ledger for channel %s
- enrollment certificate isn't a valid PEM block
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/63c03bbec2ee91aa.
Report an issue: GitHub.