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
- Confirm the target peers have joined the channel and gossip state info is flowing (peer channel list, gossip logs).
- Align client and peer versions/Fabric release.
- Retry the discovery request; state info may have been transiently missing.
- Validate TLS/network path for corruption.
- 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
- Verify peers have joined the channel before discovery queries
- Retry state-info-dependent queries once before failing
- Match Fabric versions across the network
- Check gossip state-info logs on peers
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
- failed unmarshalling alive message
- failed validating stateInfo message
- too few arguments
- Failed opening file %s: %v
- config isn't valid
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/4a5149610383bde5.
Report an issue: GitHub.