{"record":{"id":"a75037cc73819fd4","repo":"hyperledger/fabric","slug":"undefined-tag","errorCode":null,"errorMessage":"Undefined tag","messagePattern":"Undefined tag","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gossip/protoext/message.go","lineNumber":131,"sourceCode":"func IsHelloMsg(m *gossip.GossipMessage) bool {\n\treturn m.GetHello() != nil\n}\n\n// IsDigestMsg returns whether this GossipMessage is a digest message\nfunc IsDigestMsg(m *gossip.GossipMessage) bool {\n\treturn m.GetDataDig() != nil\n}\n\n// IsLeadershipMsg returns whether this GossipMessage is a leadership (leader election) message\nfunc IsLeadershipMsg(m *gossip.GossipMessage) bool {\n\treturn m.GetLeadershipMsg() != nil\n}\n\n// IsTagLegal checks the GossipMessage tags and inner type\n// and returns an error if the tag doesn't match the type.\nfunc IsTagLegal(m *gossip.GossipMessage) error {\n\tif m.Tag == gossip.GossipMessage_UNDEFINED {\n\t\treturn fmt.Errorf(\"Undefined tag\")\n\t}\n\tif IsDataMsg(m) {\n\t\tif m.Tag != gossip.GossipMessage_CHAN_AND_ORG {\n\t\t\treturn fmt.Errorf(\"Tag should be %s\", gossip.GossipMessage_Tag_name[int32(gossip.GossipMessage_CHAN_AND_ORG)])\n\t\t}\n\t\treturn nil\n\t}\n\n\tif IsAliveMsg(m) || m.GetMemReq() != nil || m.GetMemRes() != nil {\n\t\tif m.Tag != gossip.GossipMessage_EMPTY {\n\t\t\treturn fmt.Errorf(\"Tag should be %s\", gossip.GossipMessage_Tag_name[int32(gossip.GossipMessage_EMPTY)])\n\t\t}\n\t\treturn nil\n\t}\n\n\tif IsIdentityMsg(m) {\n\t\tif m.Tag != gossip.GossipMessage_ORG_ONLY {\n\t\t\treturn fmt.Errorf(\"Tag should be %s\", gossip.GossipMessage_Tag_name[int32(gossip.GossipMessage_ORG_ONLY)])","sourceCodeStart":113,"sourceCodeEnd":149,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/gossip/protoext/message.go#L113-L149","documentation":"IsTagLegal validates that a GossipMessage's Tag matches its inner message type before the gossip layer sends it. Every GossipMessage must carry a non-UNDEFINED tag; sending with Tag == GossipMessage_UNDEFINED is rejected immediately with this error.","triggerScenarios":"Calling protoext.IsTagLegal (directly or via validateMsg/Gossip send path) with a GossipMessage whose Tag field was left at its zero value GossipMessage_UNDEFINED.","commonSituations":"Constructing a GossipMessage by hand and forgetting to set Tag; a proto message deserialized from an untrusted/partial source; tests building minimal messages without setting the tag.","solutions":["Set the correct Tag for the message type (e.g. CHAN_AND_ORG for data, EMPTY for alive/membership, ORG_ONLY for identity) before sending.","Use protoext's helper constructors/ext wrappers that populate Tag automatically.","If the message came off the wire, validate before use and drop/reject it (that is what validateMsg does).","Add a unit test asserting IsTagLegal(m) == nil for every message your component sends."],"exampleFix":"// before\nmsg := &gossip.GossipMessage{ Payload: ... }\ngossipSvc.Gossip(protoext.NoopSign(msg))\n// after\nmsg := &gossip.GossipMessage{ Tag: gossip.GossipMessage_CHAN_AND_ORG, Payload: ... }\nif err := protoext.IsTagLegal(msg); err != nil { return err }\ngossipSvc.Gossip(protoext.NoopSign(msg))","handlingStrategy":"validation","validationCode":"func validGossipMessage(m *gossip.GossipMessage) bool {\n    return m != nil && m.Tag != gossip.GossipMessage_UNDEFINED && protoext.IsTagLegal(m) == nil\n}\n// guard before send:\nif !validGossipMessage(msg) { return errors.New(\"refusing to send invalid gossip message\") }","typeGuard":"func isTagged(m *gossip.GossipMessage) bool {\n    return m != nil && m.Tag != gossip.GossipMessage_UNDEFINED\n}","tryCatchPattern":"if err := protoext.IsTagLegal(msg); err != nil {\n    log.Warningf(\"dropping message with illegal tag: %v\", err)\n    return\n}","preventionTips":["Always set Tag explicitly when constructing GossipMessages.","Run IsTagLegal on outgoing messages in unit tests.","Use shared constructors/wrappers instead of raw struct literals.","Keep validateMsg in the send path enabled to catch regressions."],"tags":["hyperledger-fabric","gossip","message-validation","protobuf"],"backgroundTag":"gossip-message-tag-mismatch","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"}