{"record":{"id":"f33ddfd9926095ad","repo":"hyperledger/fabric","slug":"failed-unmarshalling-peer-s-identity","errorCode":null,"errorMessage":"failed unmarshalling peer's identity","messagePattern":"failed unmarshalling peer's identity","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"discovery/client/client.go","lineNumber":551,"sourceCode":"\t\treturn nil, errors.Errorf(\"received empty envelope(s) for endorsers for chaincode %s, channel %s\", chaincode, channel)\n\t}\n\taliveMsg, err := gprotoext.EnvelopeToGossipMessage(peer.MembershipInfo)\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"failed unmarshalling gossip envelope to alive message\")\n\t}\n\tstateInfMsg, err := gprotoext.EnvelopeToGossipMessage(peer.StateInfo)\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"failed unmarshalling gossip envelope to state info message\")\n\t}\n\tif err := validateAliveMessage(aliveMsg); err != nil {\n\t\treturn nil, errors.Wrap(err, \"failed validating alive message\")\n\t}\n\tif err := validateStateInfoMessage(stateInfMsg); err != nil {\n\t\treturn nil, errors.Wrap(err, \"failed validating stateInfo message\")\n\t}\n\tsID := &msp.SerializedIdentity{}\n\tif err := proto.Unmarshal(peer.Identity, sID); err != nil {\n\t\treturn nil, errors.Wrap(err, \"failed unmarshalling peer's identity\")\n\t}\n\treturn &Peer{\n\t\tIdentity:         peer.Identity,\n\t\tStateInfoMessage: stateInfMsg,\n\t\tAliveMessage:     aliveMsg,\n\t\tMSPID:            sID.Mspid,\n\t}, nil\n}\n\ntype endorsementDescriptor struct {\n\tendorsersByGroups map[string][]*Peer\n\tlayouts           []map[string]int\n}\n\n// NewClient creates a new Client instance\nfunc NewClient(createConnection Dialer, s Signer, signerCacheSize uint) *Client {\n\treturn &Client{\n\t\tcreateConnection: createConnection,","sourceCodeStart":533,"sourceCodeEnd":569,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/discovery/client/client.go#L533-L569","documentation":"The discovery client received a valid StateInfo/Alive pair from a peer, but the peer.Identity bytes inside the gossip AliveMessage could not be unmarshalled into an msp.SerializedIdentity proto. This identity is needed to extract the peer's MSP ID for endorsement descriptor selection, so the Peer cannot be constructed and the query fails.","triggerScenarios":"endoserser flow (createEndorsementDescriptor): proto.Unmarshal(peer.Identity, sID) fails because the Identity byte slice in the peer's gossip membership data is empty, corrupted, or not a serialized MSP identity.","commonSituations":"Peer bootstrap with a broken/missing MSP config so it gossips a malformed identity; identity format change between Fabric versions (e.g. serialized identity vs. raw cert PEM); gossip state populated before MSP was fully initialized; network truncation.","solutions":["Verify the queried peer's MSP configuration (mspConfigPath, localMSPID) is complete and valid","Re-enroll or re-issue the peer's identity (cryptogen or CA) if certs are corrupt or expired","Ensure all Fabric components are on a compatible version so identity serialization matches","Re-join the peer to the channel so gossip re-propagates a fresh valid membership record","Retry discovery against another peer to rule out one faulty node"],"exampleFix":"// before (client code silently trusting discovery response)\nresp, _ := client.Send(ctx, req)\n// after\nresp, err := client.Send(ctx, req)\nif err != nil {\n    if strings.Contains(err.Error(), \"failed unmarshalling peer's identity\") {\n        logger.Warnf(\"peer %s returned a corrupt identity; excluding it\", peerURL)\n    }\n    return nil, fmt.Errorf(\"discovery: %w\", err)\n}","handlingStrategy":"try-catch","validationCode":"func peerIdentityLooksUsable(identity []byte) error {\n    sID := &msp.SerializedIdentity{}\n    if len(identity) == 0 { return errors.New(\"empty identity\") }\n    if err := proto.Unmarshal(identity, sID); err != nil { return err }\n    if sID.Mspid == \"\" || len(sID.IdBytes) == 0 { return errors.New(\"identity missing mspid or cert\") }\n    return nil\n}","typeGuard":"func hasValidSerializedIdentity(b []byte) bool {\n    var sID msp.SerializedIdentity\n    return len(b) > 0 && proto.Unmarshal(b, &sID) == nil && sID.Mspid != \"\"\n}","tryCatchPattern":"if err != nil {\n    if strings.Contains(err.Error(), \"failed unmarshalling peer's identity\") {\n        logger.Warnf(\"peer identity corrupt; excluding peer and retrying discovery\")\n        return retryAgainstOtherPeer(ctx)\n    }\n    return err\n}","preventionTips":["Validate peer MSP config at deployment (cryptogen/CA output integrity)","Keep Fabric components version-aligned","Re-enroll peers whose certs are near expiry or corrupted"],"tags":["hyperledger-fabric","msp","identity","protobuf","discovery-service"],"backgroundTag":"identity-unmarshal-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"}