hyperledger/fabric · error

failed validating stateInfo message

Error message

failed validating stateInfo message

What it means

The StateInfo envelope parsed successfully but failed validation in validateStateInfoMessage — typically the message payload is not a GossipMessage_StateInfo, or the envelope is unsigned/empty so its content cannot be authenticated. The client rejects the whole membership result for that channel.

Source

Thrown at discovery/client/client.go:427

	return nil
}

func peersForChannel(membersRes *discovery.PeerMembershipResult, qt protoext.QueryType) ([]*Peer, error) {
	var peers []*Peer
	for org, peersOfCurrentOrg := range membersRes.PeersByOrg {
		for _, peer := range peersOfCurrentOrg.Peers {
			aliveMsg, err := gprotoext.EnvelopeToGossipMessage(peer.MembershipInfo)
			if err != nil {
				return nil, errors.Wrap(err, "failed unmarshalling alive message")
			}
			var stateInfoMsg *gprotoext.SignedGossipMessage
			if isStateInfoExpected(qt) {
				stateInfoMsg, err = gprotoext.EnvelopeToGossipMessage(peer.StateInfo)
				if err != nil {
					return nil, errors.Wrap(err, "failed unmarshalling stateInfo message")
				}
				if err := validateStateInfoMessage(stateInfoMsg); err != nil {
					return nil, errors.Wrap(err, "failed validating stateInfo message")
				}
			}
			if err := validateAliveMessage(aliveMsg); err != nil {
				return nil, errors.Wrap(err, "failed validating alive message")
			}
			peers = append(peers, &Peer{
				MSPID:            org,
				Identity:         peer.Identity,
				AliveMessage:     aliveMsg,
				StateInfoMessage: stateInfoMsg,
			})
		}
	}
	return peers, nil
}

func isStateInfoExpected(qt protoext.QueryType) bool {
	return qt != protoext.LocalMembershipQueryType

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Check peer logs for gossip state-info errors on the channel.
  2. Ensure all peers are joined to the channel and fully caught up on the ledger.
  3. Align Fabric versions between peers and the discovery client.
  4. Verify TLS configuration of the discovery service matches the client's expectations.
  5. Retry discovery; if one peer consistently fails, exclude it from discovery endpoints.

Example fix

// before: single peer endpoint
config.Endpoints = []string{"peer0:7051"}
// after: multiple healthy endpoints so one bad peer doesn't break discovery
config.Endpoints = []string{"peer0:7051", "peer1:7051"}
Defensive patterns

Strategy: validation

Validate before calling

func stateInfoIsSigned(msg *gprotoext.SignedGossipMessage) bool {
  if msg == nil || msg.Envelope == nil {
    return false
  }
  _, ok := msg.GetGossipMessage().Content.(*gossip.GossipMessage_StateInfo)
  return ok && len(msg.Envelope.PayloadSig) > 0 || len(msg.Envelope.SecretEnvelope) > 0 || msg.Envelope != nil
}

Type guard

func asStateInfo(msg *gprotoext.SignedGossipMessage) (*gossip.GossipMessage_StateInfo, bool) {
  if msg == nil { return nil, false }
  si, ok := msg.GetGossipMessage().Content.(*gossip.GossipMessage_StateInfo)
  return si.StateInfo, ok
}

Try / catch

if err != nil && strings.Contains(err.Error(), "failed validating stateInfo message") {
  log.Printf("peer returned invalid stateInfo, excluding peer: %v", err)
  return fallbackPeers(ctx)
}

Prevention

When it happens

Trigger: Chaincode/endorsement discovery queries where a peer returns StateInfo whose inner gossip message is not StateInfo type, or with a nil payload/signature so validation cannot verify it.

Common situations: Peers not fully synced with the channel; malformed responses from peers running mismatched Fabric versions; tampered or misconfigured discovery TLS endpoints.

Related errors


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