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.LocalMembershipQueryTypeView on GitHub (pinned to 2736b63f8f)
Solutions
- Check peer logs for gossip state-info errors on the channel.
- Ensure all peers are joined to the channel and fully caught up on the ledger.
- Align Fabric versions between peers and the discovery client.
- Verify TLS configuration of the discovery service matches the client's expectations.
- 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
- Ensure peers are fully synced with channel ledger
- Exclude persistently misbehaving peers from discovery endpoints
- Keep proto definitions in sync (same Fabric release)
- Verify TLS endpoints point at the intended peers
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
- failed unmarshalling stateInfo message
- failed validating alive message
- chaincode query must have at least one chaincode interest
- chaincode interest is nil
- chaincode interest must contain at least one chaincode
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/9a55da56b5bdd1a2.
Report an issue: GitHub.