{"record":{"id":"a0c61fb32589f6c3","repo":"hyperledger/fabric","slug":"block-contains-no-data","errorCode":null,"errorMessage":"block contains no data","messagePattern":"block contains no data","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"orderer/common/cluster/util.go","lineNumber":419,"sourceCode":"\n\t\tbftEnabled := bundle.ChannelConfig().Capabilities().ConsensusTypeBFT()\n\n\t\tvar consenters []*common.Consenter\n\t\tif bftEnabled {\n\t\t\tcfg, ok := bundle.OrdererConfig()\n\t\t\tif !ok {\n\t\t\t\treturn createErrorFunc(errors.New(\"no orderer section in config block\"))\n\t\t\t}\n\t\t\tconsenters = cfg.Consenters()\n\t\t}\n\n\t\treturn protoutil.BlockSignatureVerifier(bftEnabled, consenters, policy)\n\t}\n}\n\nfunc bundleFromConfigBlock(block *common.Block, bccsp bccsp.BCCSP) (*channelconfig.Bundle, protoutil.BlockVerifierFunc) {\n\tif block.Data == nil || len(block.Data.Data) == 0 {\n\t\treturn nil, createErrorFunc(errors.New(\"block contains no data\"))\n\t}\n\n\tenv := &common.Envelope{}\n\tif err := proto.Unmarshal(block.Data.Data[0], env); err != nil {\n\t\treturn nil, createErrorFunc(err)\n\t}\n\n\tbundle, err := channelconfig.NewBundleFromEnvelope(env, bccsp)\n\tif err != nil {\n\t\treturn nil, createErrorFunc(err)\n\t}\n\n\treturn bundle, nil\n}\n\nfunc createErrorFunc(err error) protoutil.BlockVerifierFunc {\n\treturn func(_ *common.BlockHeader, _ *common.BlockMetadata) error {\n\t\treturn errors.Wrap(err, \"initialized with an invalid config block\")","sourceCodeStart":401,"sourceCodeEnd":437,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/common/cluster/util.go#L401-L437","documentation":"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.","triggerScenarios":"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).","commonSituations":"Blocks corrupted on disk (truncated ledger files), blocks fetched over a broken deliver stream, or test code constructing empty blocks.","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."],"exampleFix":"// before\nblk := &common.Block{} // empty data\n// after\nenv, _ := protoutil.Marshal(&common.Envelope{Payload: payloadBytes})\nblk.Data = &common.BlockData{Data: [][]byte{env}}","handlingStrategy":"type-guard","validationCode":"// Guard against empty blocks before verification\nif block == nil || block.Data == nil || len(block.Data.Data) == 0 {\n    return errors.New(\"refusing to verify empty block\")\n}","typeGuard":"func hasBlockData(b *common.Block) bool {\n    return b != nil && b.Data != nil && len(b.Data.Data) > 0\n}","tryCatchPattern":null,"preventionTips":["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."],"tags":["fabric","block","data-corruption"],"backgroundTag":"empty-block-data","analyzedSha":"2736b63f8fd5932511d56fe68b7039d15977f7f6","analyzedAt":"2026-09-04T08:52:36.465Z","contentChangedAt":"2026-09-04T08:52:36.465Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}