{"record":{"id":"3a8928edce15071e","repo":"hyperledger/fabric","slug":"no-metadata-in-block","errorCode":null,"errorMessage":"no metadata in block","messagePattern":"no metadata in block","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"protoutil/blockutils.go","lineNumber":127,"sourceCode":"\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tif payload.Header == nil {\n\t\treturn \"\", errors.New(\"failed to retrieve channel id - payload header is empty\")\n\t}\n\tchdr, err := UnmarshalChannelHeader(payload.GetHeader().GetChannelHeader())\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\treturn chdr.ChannelId, nil\n}\n\n// GetMetadataFromBlock retrieves metadata at the specified index.\nfunc GetMetadataFromBlock(block *cb.Block, index cb.BlockMetadataIndex) (*cb.Metadata, error) {\n\tif block.Metadata == nil {\n\t\treturn nil, errors.New(\"no metadata in block\")\n\t}\n\n\tif len(block.Metadata.Metadata) <= int(index) {\n\t\treturn nil, errors.Errorf(\"no metadata at index [%s]\", index)\n\t}\n\n\tmd := &cb.Metadata{}\n\terr := proto.Unmarshal(block.Metadata.Metadata[index], md)\n\tif err != nil {\n\t\treturn nil, errors.Wrapf(err, \"error unmarshalling metadata at index [%s]\", index)\n\t}\n\treturn md, nil\n}\n\n// GetMetadataFromBlockOrPanic retrieves metadata at the specified index, or\n// panics on error\nfunc GetMetadataFromBlockOrPanic(block *cb.Block, index cb.BlockMetadataIndex) *cb.Metadata {\n\tmd, err := GetMetadataFromBlock(block, index)","sourceCodeStart":109,"sourceCodeEnd":145,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/protoutil/blockutils.go#L109-L145","documentation":"GetMetadataFromBlock retrieves the cb.Metadata message at a given BlockMetadataIndex. It returns 'no metadata in block' when block.Metadata is nil, i.e. the block carries no metadata section at all, so no index can be read. This is a precondition check before index bounds and unmarshalling.","triggerScenarios":"Calling GetMetadataFromBlock (directly or via GetMetadataFromBlockOrPanic, GetConsenterMetadataFromBlock, GetLastConfigIndexFromBlock, verifyBlockDataAndMetadata) on a block whose Metadata field is nil.","commonSituations":"Blocks constructed programmatically in tests without Metadata; corrupted ledger entries with stripped metadata; genesis blocks from tooling that omits metadata; deserialization paths that partially populate cb.Block.","solutions":["Guard callers with if block.Metadata == nil before calling, or use GetMetadataFromBlockOrPanic only where nil is impossible","Ensure blocks always come from protoutil/ledger write paths that populate metadata (commitBlock with WriteBlock)","Regenerate or re-fetch the block if the ledger is corrupt","Fix test builders to set Metadata with the required indices (SIGNATURES, LAST_CONFIG, ORDERER)"],"exampleFix":"// before\nmd, err := protoutil.GetMetadataFromBlock(blk, cb.BlockMetadataIndex_SIGNATURES)\n// after\nif blk == nil || blk.Metadata == nil {\n    return errors.New(\"block has no metadata\")\n}\nmd, err := protoutil.GetMetadataFromBlock(blk, cb.BlockMetadataIndex_SIGNATURES)","handlingStrategy":"type-guard","validationCode":"if blk == nil || blk.Metadata == nil {\n    return errors.New(\"block has no metadata section\")\n}\nmd, err := protoutil.GetMetadataFromBlock(blk, cb.BlockMetadataIndex_SIGNATURES)","typeGuard":"func hasMetadataSection(b *cb.Block) bool {\n    return b != nil && b.Metadata != nil\n}","tryCatchPattern":"md, err := protoutil.GetMetadataFromBlock(blk, idx)\nif err != nil {\n    if err.Error() == \"no metadata in block\" {\n        log.Warnf(\"block %d lacks metadata; treating as invalid\", blk.Header.Number)\n        return errInvalidBlock\n    }\n    return err\n}","preventionTips":["Produce blocks only via ledger/protoutil write paths that always populate Metadata","Fix test builders to include Metadata with SIGNATURES, LAST_CONFIG, ORDERER entries","Treat nil-metadata blocks as invalid at ingestion time","Guard all direct field access with nil checks before helper calls"],"tags":["block","metadata","protoutil","input-validation"],"backgroundTag":"missing-block-metadata","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"}