hyperledger/fabric · error
Invalid PullMsgType: %s
Error message
Invalid PullMsgType: %s
What it means
Sentinel-style validation guard in IsTagLegal: a pull-type GossipMessage (BLOCK_MSG or IDENTITY_MSG) carries a Tag that does not match the tag required for its pull message type, so the message is rejected before further processing. The %s is the name of the expected tag (e.g. CHAN_AND_ORG or EMPTY).
Source
Thrown at gossip/protoext/message.go:167
return fmt.Errorf("Tag should be %s", gossip.GossipMessage_Tag_name[int32(gossip.GossipMessage_ORG_ONLY)])
}
return nil
}
if IsPullMsg(m) {
switch GetPullMsgType(m) {
case gossip.PullMsgType_BLOCK_MSG:
if m.Tag != gossip.GossipMessage_CHAN_AND_ORG {
return fmt.Errorf("Tag should be %s", gossip.GossipMessage_Tag_name[int32(gossip.GossipMessage_CHAN_AND_ORG)])
}
return nil
case gossip.PullMsgType_IDENTITY_MSG:
if m.Tag != gossip.GossipMessage_EMPTY {
return fmt.Errorf("Tag should be %s", gossip.GossipMessage_Tag_name[int32(gossip.GossipMessage_EMPTY)])
}
return nil
default:
return fmt.Errorf("Invalid PullMsgType: %s", gossip.PullMsgType_name[int32(GetPullMsgType(m))])
}
}
if IsStateInfoMsg(m) || IsStateInfoPullRequestMsg(m) || IsStateInfoSnapshot(m) || IsRemoteStateMessage(m) {
if m.Tag != gossip.GossipMessage_CHAN_OR_ORG {
return fmt.Errorf("Tag should be %s", gossip.GossipMessage_Tag_name[int32(gossip.GossipMessage_CHAN_OR_ORG)])
}
return nil
}
if IsLeadershipMsg(m) {
if m.Tag != gossip.GossipMessage_CHAN_AND_ORG {
return fmt.Errorf("Tag should be %s", gossip.GossipMessage_Tag_name[int32(gossip.GossipMessage_CHAN_AND_ORG)])
}
return nil
}
return fmt.Errorf("Unknown message type: %v", m)View on GitHub (pinned to 2736b63f8f)
Solutions
- Only send PullMsgType_BLOCK_MSG or PullMsgType_IDENTITY_MSG pull messages
- Check enum values against gossip.PullMsgType_name to ensure a defined type is set
- Upgrade fabric so the validator recognizes any newly added pull message type
Example fix
// before
msg.Content = &gossip.GossipMessage_PullMsg{PullMsgType: gossip.PullMsgType(9)}
// after
msg.Content = &gossip.GossipMessage_PullMsg{PullMsgType: gossip.PullMsgType_BLOCK_MSG} Defensive patterns
Strategy: validation
Validate before calling
t := protoext.GetPullMsgType(msg)
if t != gossip.PullMsgType_BLOCK_MSG && t != gossip.PullMsgType_IDENTITY_MSG {
return fmt.Errorf("unsupported pull msg type: %v", t)
} Type guard
func hasKnownPullType(m *gossip.GossipMessage) bool {
t := protoext.GetPullMsgType(m)
return t == gossip.PullMsgType_BLOCK_MSG || t == gossip.PullMsgType_IDENTITY_MSG
} Prevention
- Only use the named PullMsgType enum constants
- Keep fabric versions aligned across peers
- Check gossip.PullMsgType_name to confirm the type is defined
When it happens
Trigger: Calling IsTagLegal on a message where GetPullMsgType(m) returns a value not in {BLOCK_MSG, IDENTITY_MSG} — e.g. an uninitialized, zero-but-unknown enum value, or a payload set as pull without a valid PullMsgType.
Common situations: Proto evolution adding a new PullMsgType not yet handled by this validator; corrupted or truncated payloads misdecoded as pull messages; hand-built test messages with arbitrary pull types.
Related errors
- message isn't an alive message
- message isn't a stateInfo message
- Unknown message type: %v
- Invalid Peer Identity. It must be different from nil.
- '%s' not equal <newest|oldest|config|(number)>
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/59b98cc5381fe310.
Report an issue: GitHub.