hyperledger/fabric · error
block from orderer could not be re-marshaled: proto: Marshal
Error message
block from orderer could not be re-marshaled: proto: Marshal called with nil
What it means
GossipBlockHandler.HandleBlock returns this fixed-message error when the block received from the orderer is nil, before attempting proto.Marshal. The message text mirrors the proto error that marshaling a nil message would produce ('proto: Marshal called with nil'), so callers can treat it uniformly. It signals the orderer/gossip path handed the handler an invalid block.
Source
Thrown at core/deliverservice/gossip_block_handler.go:37
//
//go:generate counterfeiter -o fake/gossip_service_adapter.go --fake-name GossipServiceAdapter . GossipServiceAdapter
type GossipServiceAdapter interface {
// AddPayload adds payload to the local state sync buffer
AddPayload(chainID string, payload *gossip.Payload) error
// Gossip the message across the peers
Gossip(msg *gossip.GossipMessage)
}
type GossipBlockHandler struct {
gossip GossipServiceAdapter
blockGossipDisabled bool
logger *flogging.FabricLogger
}
func (h *GossipBlockHandler) HandleBlock(channelID string, block *common.Block) error {
if block == nil {
return errors.New("block from orderer could not be re-marshaled: proto: Marshal called with nil")
}
marshaledBlock, err := proto.Marshal(block)
if err != nil {
return errors.WithMessage(err, "block from orderer could not be re-marshaled")
}
// Create payload with a block received
blockNum := block.GetHeader().GetNumber()
payload := &gossip.Payload{
Data: marshaledBlock,
SeqNum: blockNum,
}
// Use payload to create gossip message
gossipMsg := &gossip.GossipMessage{
Nonce: 0,
Tag: gossip.GossipMessage_CHAN_AND_ORG,
Channel: []byte(channelID),View on GitHub (pinned to 2736b63f8f)
Solutions
- Fix the upstream producer so it never invokes HandleBlock with a nil block; add a nil check before calling it
- Log and drop the nil block on the caller side, resyncing blocks via the normal delivery stream
- Upgrade orderer/peer to matching versions to rule out serialization bugs
- If persistent, capture orderer logs and file an issue; restart the delivery service to re-establish the block stream
Example fix
// before
handler.HandleBlock(channelID, blockFromOrderer) // block may be nil
// after
if blockFromOrderer == nil {
logger.Warningf("skipping nil block for channel %s", channelID)
return
}
handler.HandleBlock(channelID, blockFromOrderer) Defensive patterns
Strategy: type-guard
Validate before calling
if block == nil || block.Header == nil {
logger.Warningf("invalid block from orderer for channel %s", channelID)
return
}
HandleBlock(channelID, block) Type guard
func isValidBlock(b *common.Block) bool {
return b != nil && b.Header != nil && b.Data != nil
} Try / catch
if err := handler.HandleBlock(channelID, blk); err != nil {
if strings.Contains(err.Error(), "could not be re-marshaled") {
logger.Errorf("dropping invalid block on %s: %v", channelID, err)
return nil
}
return err
} Prevention
- Nil-check blocks at every boundary in the gossip/delivery pipeline
- Keep orderer and peer on compatible Fabric versions
- Monitor delivery stream health to detect upstream nil/short reads early
When it happens
Trigger: HandleBlock(channelID, block) is invoked with block == nil, e.g. a nil block propagated from the deliver client or gossip pipeline.
Common situations: Orderer disconnects or upstream bugs yielding nil blocks; version mismatches between orderer and peer; corrupted internal state in the block delivery pipeline; tests invoking HandleBlock with nil to simulate bad input.
Related errors
- expected collection config of type CollectionConfig_StaticCo
- Undefined tag
- Failed unmarshalling GossipMessage from envelope: %v
- malformed org definition for org: %s
- error encode input
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/18a62c542bfede3f.
Report an issue: GitHub.