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

  1. Only send PullMsgType_BLOCK_MSG or PullMsgType_IDENTITY_MSG pull messages
  2. Check enum values against gossip.PullMsgType_name to ensure a defined type is set
  3. 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

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


AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04). Data as JSON: /api/errors/59b98cc5381fe310. Report an issue: GitHub.