{"record":{"id":"d028cf5e7393f1d1","repo":"hyperledger/fabric","slug":"properties-is-nil","errorCode":null,"errorMessage":"properties is nil","messagePattern":"properties is nil","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"discovery/client/client.go","lineNumber":598,"sourceCode":"\tif m == nil {\n\t\treturn errors.New(\"membership is empty\")\n\t}\n\tif am.Timestamp == nil {\n\t\treturn errors.New(\"timestamp is nil\")\n\t}\n\treturn nil\n}\n\nfunc validateStateInfoMessage(message *gprotoext.SignedGossipMessage) error {\n\tsi := message.GetStateInfo()\n\tif si == nil {\n\t\treturn errors.New(\"message isn't a stateInfo message\")\n\t}\n\tif si.Timestamp == nil {\n\t\treturn errors.New(\"timestamp is nil\")\n\t}\n\tif si.Properties == nil {\n\t\treturn errors.New(\"properties is nil\")\n\t}\n\treturn nil\n}\n\nfunc validateInterests(interests ...*peer.ChaincodeInterest) error {\n\tif len(interests) == 0 {\n\t\treturn errors.New(\"no chaincode interests given\")\n\t}\n\tfor _, interest := range interests {\n\t\tif interest == nil {\n\t\t\treturn errors.New(\"chaincode interest is nil\")\n\t\t}\n\t\tif err := InvocationChain(interest.Chaincodes).ValidateInvocationChain(); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}","sourceCodeStart":580,"sourceCodeEnd":616,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/discovery/client/client.go#L580-L616","documentation":"validateStateInfoMessage requires StateInfo.Properties to be non-nil; Properties carries ledger height, chaincodes installed, and roles, which the discovery client needs to rank endorsers. Missing properties means the client cannot evaluate the peer for endorsement, so validation fails.","triggerScenarios":"A discovery response StateInfo lacks Properties — the peer did not include its ledger/chaincode metadata in its state info, or the payload was truncated.","commonSituations":"Peer running a Fabric version whose StateInfo omits Properties; peer still initializing its ledger when queried; protobuf decode dropping the field due to corruption or version skew.","solutions":["Wait until the peer finishes catching up its ledger, then retry discovery","Upgrade the peer to a Fabric version compatible with the rest of the network","Restart the peer so it regenerates StateInfo with Properties","Retry discovery against a different, fully synced peer"],"exampleFix":"// before\npeers, err := resp.ForChannel(\"mychannel\")\n// after\npeers, err := resp.ForChannel(\"mychannel\")\nif err != nil && strings.Contains(err.Error(), \"properties is nil\") {\n    logger.Warnf(\"peer state info lacks properties; peer ledger may not be synced yet\")\n    return retryDiscovery(ctx)\n}","handlingStrategy":"validation","validationCode":"func stateInfoHasProperties(m *gprotoext.SignedGossipMessage) bool {\n    si := m.GetStateInfo()\n    return si != nil && si.Properties != nil && si.Properties.LedgerHeight > 0\n}","typeGuard":"func hasStateInfoProperties(m *gprotoext.SignedGossipMessage) bool {\n    si := m.GetStateInfo()\n    return si != nil && si.Properties != nil\n}","tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"properties is nil\") {\n    logger.Warnf(\"peer state info lacks properties; ledger may still be syncing\")\n    time.Sleep(backoff)\n    return retryDiscovery(ctx)\n}","preventionTips":["Wait for ledger catch-up before issuing discovery queries","Verify peers report chaincodes via peer chaincode list","Keep peer versions uniform across the network"],"tags":["hyperledger-fabric","gossip","stateinfo","ledger","endorsement"],"backgroundTag":"discovery-stateinfo-validation-failed","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"}