hyperledger/fabric · error
Block data is empty
Error message
Block data is empty
What it means
coordinator.StoreBlock validates the incoming common.Block before committing it to the ledger and returns this error when block.Data is nil. A block without data payload cannot be validated or committed, so it is rejected immediately.
Source
Thrown at gossip/privdata/coordinator.go:155
) Coordinator {
return &coordinator{
Support: support,
mspID: mspID,
store: store,
selfSignedData: selfSignedData,
transientBlockRetention: config.TransientBlockRetention,
logger: logger.With("channel", support.ChainID),
metrics: metrics,
pullRetryThreshold: config.PullRetryThreshold,
skipPullingInvalidTransactions: config.SkipPullingInvalidTransactions,
idDeserializerFactory: idDeserializerFactory,
}
}
// StoreBlock stores block with private data into the ledger
func (c *coordinator) StoreBlock(block *common.Block, privateDataSets util.PvtDataCollections) error {
if block.Data == nil {
return errors.New("Block data is empty")
}
if block.Header == nil {
return errors.New("Block header is nil")
}
c.logger.Infof("Received block [%d] from buffer", block.Header.Number)
c.logger.Debugf("Validating block [%d]", block.Header.Number)
validationStart := time.Now()
err := c.Validator.Validate(block)
c.reportValidationDuration(time.Since(validationStart))
if err != nil {
c.logger.Errorf("Validation failed: %+v", err)
return err
}
blockAndPvtData := &ledger.BlockAndPvtData{View on GitHub (pinned to 2736b63f8f)
Solutions
- Re-fetch the block from the orderer or a peer via block delivery/delclient
- Discard or re-request the corrupted block from gossip source
- Verify block deserialization (protoutil) succeeded before calling StoreBlock
- In test/repair code, always populate block.Data before storing
Example fix
// before
coordinator.StoreBlock(&common.Block{}, nil)
// after
blk := &common.Block{Header: header, Data: &common.BlockData{Data: [][]byte{...}}}
if blk.Data == nil || blk.Header == nil {
return errors.New("refusing to store incomplete block")
}
coordinator.StoreBlock(blk, pvtData) Defensive patterns
Strategy: validation
Validate before calling
if block == nil || block.Data == nil {
return errors.New("cannot store block: data is nil")
}
if err := coordinator.StoreBlock(block, pvtData); err != nil { ... } Type guard
func blockComplete(b *common.Block) bool {
return b != nil && b.Data != nil && b.Header != nil
} Prevention
- Validate blocks (protoutil) before feeding them to the committer
- Only source blocks from the orderer or validated peers
- Check gossip block-fetch integrity on repeated failures
- Populate Data and Header in test block fixtures
When it happens
Trigger: Calling StoreBlock with a block whose Data field is nil — e.g. a malformed block fetched from gossip/orderer, a partially deserialized block, or a hand-constructed block in tests.
Common situations: Corrupted gossip transfer of blocks; orderer returning truncated blocks; off-chain ledger repair tooling feeding empty blocks; unit tests constructing common.Block without Data.
Related errors
- Block header is nil
- commit failed
- Block.Metadata is nil or Block.Metadata lacks a Tx filter bi
- block data size(%d) is different from Tx filter size(%d)
- invalid key [%s], cannot begin with "_"
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/c141c33f5109cb1f.
Report an issue: GitHub.