hyperledger/fabric · error
block contains no data
Error message
block contains no data
What it means
bundleFromConfigBlock requires the block's Data field to contain at least one envelope. When block.Data is nil or block.Data.Data is empty, the block cannot contain a config transaction, so the returned verifier always fails with this wrapped error.
Source
Thrown at orderer/common/cluster/util.go:419
bftEnabled := bundle.ChannelConfig().Capabilities().ConsensusTypeBFT()
var consenters []*common.Consenter
if bftEnabled {
cfg, ok := bundle.OrdererConfig()
if !ok {
return createErrorFunc(errors.New("no orderer section in config block"))
}
consenters = cfg.Consenters()
}
return protoutil.BlockSignatureVerifier(bftEnabled, consenters, policy)
}
}
func bundleFromConfigBlock(block *common.Block, bccsp bccsp.BCCSP) (*channelconfig.Bundle, protoutil.BlockVerifierFunc) {
if block.Data == nil || len(block.Data.Data) == 0 {
return nil, createErrorFunc(errors.New("block contains no data"))
}
env := &common.Envelope{}
if err := proto.Unmarshal(block.Data.Data[0], env); err != nil {
return nil, createErrorFunc(err)
}
bundle, err := channelconfig.NewBundleFromEnvelope(env, bccsp)
if err != nil {
return nil, createErrorFunc(err)
}
return bundle, nil
}
func createErrorFunc(err error) protoutil.BlockVerifierFunc {
return func(_ *common.BlockHeader, _ *common.BlockMetadata) error {
return errors.Wrap(err, "initialized with an invalid config block")View on GitHub (pinned to 2736b63f8f)
Solutions
- Check that the block source (file/ledger/puller) is intact; re-pull the config block from a healthy orderer.
- Verify the block was unmarshaled correctly and is not the result of a failed decode.
- If using a local snapshot/s copy of blocks, re-export them from the network.
- In tests, populate block.Data.Data with a marshaled envelope rather than passing an empty block.
Example fix
// before
blk := &common.Block{} // empty data
// after
env, _ := protoutil.Marshal(&common.Envelope{Payload: payloadBytes})
blk.Data = &common.BlockData{Data: [][]byte{env}} Defensive patterns
Strategy: type-guard
Validate before calling
// Guard against empty blocks before verification
if block == nil || block.Data == nil || len(block.Data.Data) == 0 {
return errors.New("refusing to verify empty block")
} Type guard
func hasBlockData(b *common.Block) bool {
return b != nil && b.Data != nil && len(b.Data.Data) > 0
} Prevention
- Verify integrity (hashes) of blocks read from disk before use.
- Re-pull blocks over deliver rather than trusting local corrupted files.
- In tests, always populate Data with a marshaled envelope.
When it happens
Trigger: Passing a nil-data block, an uninitialized *common.Block, or a config block whose payload was stripped/truncated, to the verifier factory (indirectly via EndpointconfigFromConfigBlock consumers).
Common situations: Blocks corrupted on disk (truncated ledger files), blocks fetched over a broken deliver stream, or test code constructing empty blocks.
Related errors
- BlockDataHashStructure width only supported at MaxUint32 in
- cannot unmarshal file part %s into a block
- too few arguments
- chaincode type not supported: %s
- incorrect number of arguments
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/a0c61fb32589f6c3.
Report an issue: GitHub.