{"record":{"id":"f8a5fc93b383babe","repo":"hyperledger/fabric","slug":"empty-block-f8a5fc","errorCode":null,"errorMessage":"empty block","messagePattern":"empty block","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"protoutil/blockutils.go","lineNumber":318,"sourceCode":"\t\treturn policy.EvaluateSignedData(signatureSet)\n\t}\n}\n\nfunc searchConsenterIdentityByID(consenters []*cb.Consenter, identifier uint32) []byte {\n\tfor _, consenter := range consenters {\n\t\tif consenter.Id == identifier {\n\t\t\treturn MarshalOrPanic(&msp.SerializedIdentity{\n\t\t\t\tMspid:   consenter.MspId,\n\t\t\t\tIdBytes: consenter.Identity,\n\t\t\t})\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc VerifyTransactionsAreWellFormed(bd *cb.BlockData) error {\n\tif bd == nil || bd.Data == nil || len(bd.Data) == 0 {\n\t\treturn errors.New(\"empty block\")\n\t}\n\n\t// If we have a single transaction, and the block is a config block, then no need to check\n\t// well formed-ness, because there cannot be another transaction in the original block.\n\tif HasConfigTx(bd) {\n\t\treturn nil\n\t}\n\n\tfor i, rawTx := range bd.Data {\n\t\tenv := &cb.Envelope{}\n\t\tif err := proto.Unmarshal(rawTx, env); err != nil {\n\t\t\treturn fmt.Errorf(\"transaction %d is invalid: %v\", i, err)\n\t\t}\n\n\t\tif len(env.Payload) == 0 {\n\t\t\treturn fmt.Errorf(\"transaction %d has no payload\", i)\n\t\t}\n","sourceCodeStart":300,"sourceCodeEnd":336,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/protoutil/blockutils.go#L300-L336","documentation":"VerifyTransactionsAreWellFormed checks that every envelope in a block's data can be parsed. If the BlockData pointer, its Data slice, or the slice contents are absent, there is nothing to validate, so it returns this error. It is a structural guard ensuring blocks handed to hashing/verification contain transactions.","triggerScenarios":"Calling VerifyTransactionsAreWellFormed with a nil *cb.BlockData, a nil Data field, or a zero-length Data slice — e.g. a block constructed without data or a decoded block missing payload bytes.","commonSituations":"Test harnesses creating empty blocks, ledger code reading a truncated/empty block record, or plumbing bugs where the envelope slice is dropped before hashing (BlockDataHash path).","solutions":["Check that the block was fully populated by its producer before calling; log the block number and data length","Reject empty blocks upstream (before hashing) with a descriptive error","If the block came from a ledger, treat it as corrupt and re-fetch or rebuild","In tests, seed cb.BlockData with at least one valid envelope or a config transaction"],"exampleFix":"// before\nerr := VerifyTransactionsAreWellFormed(block.Data)\n// after\nif block == nil || block.Data == nil || len(block.Data.Data) == 0 {\n    return errors.Errorf(\"block %v has empty data; refusing to hash/verify\", block)\n}\nerr := VerifyTransactionsAreWellFormed(block.Data)","handlingStrategy":"validation","validationCode":"if block == nil || block.Data == nil || len(block.Data.Data) == 0 {\n    return errors.New(\"refusing to verify/hash an empty block\")\n}\nerr := VerifyTransactionsAreWellFormed(block.Data)","typeGuard":"func isNonEmptyBlockData(bd *cb.BlockData) bool {\n    return bd != nil && bd.Data != nil && len(bd.Data) > 0\n}","tryCatchPattern":"if err := VerifyTransactionsAreWellFormed(block.Data); err != nil {\n    return fmt.Errorf(\"block %d not well formed: %w\", block.GetHeader().GetNumber(), err)\n}","preventionTips":["Validate block structure immediately after decode, before hashing","In tests, always populate Data with at least one envelope or a config tx","Treat empty blocks from a ledger as corruption and re-fetch","Check HasConfigTx expectations when a block should be a config block"],"tags":["validation","block-data","empty-input"],"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"}