{"record":{"id":"534504aa54e94645","repo":"hyperledger/fabric","slug":"buffer-is-empty","errorCode":null,"errorMessage":"buffer is empty","messagePattern":"buffer is empty","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"orderer/common/cluster/util.go","lineNumber":750,"sourceCode":"\t\treturn errors.New(\"signature invalid\")\n\t}\n\treturn nil\n}\n\nfunc SHA256Digest(data []byte) []byte {\n\thash := sha256.Sum256(data)\n\treturn hash[:]\n}\n\n// VerifyBlocksBFT verifies the given consecutive sequence of blocks is valid, always verifies signature,\n// and returns nil if it's valid, else an error.\nfunc VerifyBlocksBFT(blocks []*common.Block, signatureVerifier protoutil.BlockVerifierFunc, vb protoutil.VerifierBuilder) error {\n\treturn verifyBlockSequence(blocks, signatureVerifier, vb)\n}\n\nfunc verifyBlockSequence(blockBuff []*common.Block, signatureVerifier protoutil.BlockVerifierFunc, vb protoutil.VerifierBuilder) error {\n\tif len(blockBuff) == 0 {\n\t\treturn errors.New(\"buffer is empty\")\n\t}\n\n\t// Verify all configuration blocks that are found inside the block batch,\n\t// with the configuration that was committed (nil) or with one that is picked up\n\t// during iteration over the block batch.\n\tfor i, block := range blockBuff {\n\t\tif err := VerifyBlockHash(i, blockBuff); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tconfigFromBlock, err := deliverclient.ConfigFromBlock(block)\n\n\t\tif err != nil && err != deliverclient.ErrNotAConfig {\n\t\t\treturn err\n\t\t}\n\n\t\tif err := VerifyBlockSignature(block, signatureVerifier); err != nil {\n\t\t\t// Genesis blocks are not signed, so silently ignore the error\n\t\t\tif block.Header.Number > 0 {","sourceCodeStart":732,"sourceCodeEnd":768,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/common/cluster/util.go#L732-L768","documentation":"verifyBlockSequence (used by VerifyBlocks / VerifyBlocksBFT) requires a non-empty batch of blocks to verify. An empty slice provides nothing to anchor configuration or signature verification, so it returns this guard error immediately.","triggerScenarios":"Calling VerifyBlocks or VerifyBlocksBFT with a zero-length []*common.Block slice — e.g. a Replicator feeding an empty block buffer pulled from an empty filter result, or a caller that already drained the buffer before verification.","commonSituations":"Custom replication/consenter logic passing filtered block slices that ended up empty; off-by-one slicing (blocks[start:end] with start==end); wiring a nil/empty buffer in tests.","solutions":["Check the caller that builds the block buffer — only invoke verification when at least one block was pulled","Inspect the slicing/pagination logic that produced blocks[start:end] for an off-by-one empty window","Log len(blocks) at the call site to confirm the batch before verification","In code paths that legitimately receive empty batches, skip verification instead of calling it"],"exampleFix":"// before\nerr := VerifyBlocksBFT(receivedBlocks, verifier, vb) // receivedBlocks may be empty\n// after\nif len(receivedBlocks) == 0 {\n    return nil // nothing to verify\n}\nerr := VerifyBlocksBFT(receivedBlocks, verifier, vb)","handlingStrategy":"validation","validationCode":"if len(blocks) == 0 {\n    return errors.New(\"nothing to verify: block batch is empty\")\n}","typeGuard":"func hasBlocks(blocks []*common.Block) bool { return len(blocks) > 0 }","tryCatchPattern":"err := cluster.VerifyBlocksBFT(blocks, verifier, vb)\nif err != nil && strings.Contains(err.Error(), \"buffer is empty\") {\n    logger.Warning(\"received empty block batch; skipping verification\")\n    return nil\n}","preventionTips":["Guard call sites with len(blocks) > 0 before verification","Review slicing expressions blocks[i:j] for empty windows","Log batch sizes at pull/filter time","Return early on empty pull results instead of delegating to the verifier"],"tags":["blocks","bft","validation"],"backgroundTag":"empty-block-batch","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"}