hyperledger/fabric · error

failed unmarshalling stateInfo message

Error message

failed unmarshalling stateInfo message

What it means

Same as the alive-message error but for the StateInfo envelope: when the query type requires state info (e.g. chaincode or endorsement queries), the client parses peer.StateInfo into a SignedGossipMessage and wraps any parse failure with this message. The server returned a StateInfo envelope that is nil, truncated, or not a valid gossip message.

Source

Thrown at discovery/client/client.go:424

		resp[key] = peers
	}
	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
}

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Confirm the target peers have joined the channel and gossip state info is flowing (peer channel list, gossip logs).
  2. Align client and peer versions/Fabric release.
  3. Retry the discovery request; state info may have been transiently missing.
  4. Validate TLS/network path for corruption.
  5. Fall back to peers that returned valid state info.

Example fix

// before
res, _ := client.SendRequest(ctx, req) // req included chaincode query
// after: catch and retry once against another peer
res, err := client.SendRequest(ctx, req)
if err != nil && strings.Contains(err.Error(), "failed unmarshalling stateInfo message") {
  res, err = client.SendRequest(ctx, reqWithAlternatePeers)
}
Defensive patterns

Strategy: validation

Validate before calling

func hasStateInfo(p *discovery.Peer) bool {
  return p != nil && p.StateInfo != nil && len(p.StateInfo.Payload) > 0
}

Type guard

func isStateInfoMessage(msg *gprotoext.SignedGossipMessage) bool {
  return msg != nil && msg.IsStateInfoMsg()
}

Try / catch

if err != nil {
  if strings.Contains(err.Error(), "failed unmarshalling stateInfo message") {
    return retryDiscovery(ctx, req) // transient: state info may arrive later
  }
  return err
}

Prevention

When it happens

Trigger: A discovery request including a state-info-dependent query (ChaincodeQuery, EndorsementQuery, ConfigQuery paths where isStateInfoExpected(qt) is true) whose response entries contain invalid peer.StateInfo envelopes.

Common situations: Peer that has not yet joined/gossiped state info for the channel; version skew between client and peer protos; corrupted responses from a network middlebox; stale peer membership entries.

Understand the failure class

Background: "cannot parse invalid wire-format data", "cannot unmarshal", "failed unmarshalling": protobuf unmarshal errors explained — this error's family across 10 libraries.

Related errors


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