{"record":{"id":"36c57c7a4ba9930e","repo":"hyperledger/fabric","slug":"block-data-is-nil","errorCode":null,"errorMessage":"block data is nil","messagePattern":"block data is nil","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"orderer/common/cluster/deliver.go","lineNumber":462,"sourceCode":"\t}\n\n\tif err = stream.Send(env); err != nil {\n\t\tp.Logger.Errorf(\"Failed sending seek envelope to %s: %v\", endpoint, err)\n\t\tstream.abort()\n\t\treturn nil, err\n\t}\n\treturn stream, nil\n}\n\nfunc extractBlockFromResponse(resp *orderer.DeliverResponse) (*common.Block, error) {\n\tswitch t := resp.Type.(type) {\n\tcase *orderer.DeliverResponse_Block:\n\t\tblock := t.Block\n\t\tif block == nil {\n\t\t\treturn nil, errors.New(\"block is nil\")\n\t\t}\n\t\tif block.Data == nil {\n\t\t\treturn nil, errors.New(\"block data is nil\")\n\t\t}\n\t\tif block.Header == nil {\n\t\t\treturn nil, errors.New(\"block header is nil\")\n\t\t}\n\t\tif block.Metadata == nil || len(block.Metadata.Metadata) == 0 {\n\t\t\treturn nil, errors.New(\"block metadata is empty\")\n\t\t}\n\t\treturn block, nil\n\tcase *orderer.DeliverResponse_Status:\n\t\tif t.Status == common.Status_FORBIDDEN {\n\t\t\treturn nil, ErrForbidden\n\t\t}\n\t\tif t.Status == common.Status_SERVICE_UNAVAILABLE {\n\t\t\treturn nil, ErrServiceUnavailable\n\t\t}\n\t\treturn nil, errors.Errorf(\"faulty node, received: %v\", resp)\n\tdefault:\n\t\treturn nil, errors.Errorf(\"response is of type %v, but expected a block\", reflect.TypeOf(resp.Type))","sourceCodeStart":444,"sourceCodeEnd":480,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/common/cluster/deliver.go#L444-L480","documentation":"extractBlockFromResponse guard: a DeliverResponse_Block arrived whose Block.Data is nil. A structurally valid Fabric block always carries a data section, so the remote orderer (or the stream) produced a malformed/empty block; used by block pulling and last-block-sequence fetch during RAFT replication.","triggerScenarios":"extractBlockFromResponse received a DeliverResponse_Block where block.Data is nil, i.e. the remote deliver service sent a block header without data.","commonSituations":"Corrupted block storage or serialization bug on the source orderer; version incompatibility producing partially-populated block protos.","solutions":["Pull the block from a different orderer endpoint","Check the source node's ledger/file integrity and restart it if corrupted","Upgrade mismatched fabric binaries so block serialization is consistent"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if block := resp.GetBlock(); block != nil && block.Data == nil {\n    return fmt.Errorf(\"block data missing in response\")\n}","typeGuard":"func hasBlockData(resp *orderer.DeliverResponse) bool {\n    return resp.GetBlock() != nil && resp.GetBlock().Data != nil\n}","tryCatchPattern":"block, err := extractBlockFromResponse(resp)\nif err != nil {\n    return fmt.Errorf(\"skipping invalid block from %s: %w\", endpoint, err)\n}","preventionTips":["Verify source node ledger integrity if empty-data blocks recur","Retry the fetch from another orderer","Avoid proxies that mangle large protobuf messages"],"tags":["deliver","block-sync","malformed-response"],"backgroundTag":"malformed-block-response","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"}