hyperledger/fabric · error

Block.Metadata is nil or Block.Metadata lacks a Tx filter bi

Error message

Block.Metadata is nil or Block.Metadata lacks a Tx filter bitmap

What it means

getTxPvtdataInfoFromBlock reads the transaction-filter bitmap stored in block.Metadata at index BlockMetadataIndex_TRANSACTIONS_FILTER to determine which txs are valid. If block.Metadata is nil, or the metadata array is too short to contain the filter, the block is considered malformed for private-data purposes and this error is returned.

Source

Thrown at gossip/privdata/coordinator.go:299

				if !isAuthorized(peerAuthInfo) {
					c.logger.Debugf("Skipping collection criteria [%#v] because peer isn't authorized", cc)
					continue
				}
				seqs2Namespaces.addCollection(uint64(seqInBlock), txPvtDataItem.WriteSet.DataModel, ns.Namespace, col)
			}
		}
	}

	return blockAndPvtData.Block, seqs2Namespaces.asPrivateData(), nil
}

// getTxPvtdataInfoFromBlock parses the block transactions and returns the list of private data items in the block.
// Note that this peer's eligibility for the private data is not checked here.
func (c *coordinator) getTxPvtdataInfoFromBlock(block *common.Block) ([]*ledger.TxPvtdataInfo, error) {
	txPvtdataItemsFromBlock := []*ledger.TxPvtdataInfo{}

	if block.Metadata == nil || len(block.Metadata.Metadata) <= int(common.BlockMetadataIndex_TRANSACTIONS_FILTER) {
		return nil, errors.New("Block.Metadata is nil or Block.Metadata lacks a Tx filter bitmap")
	}
	txsFilter := txValidationFlags(block.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER])
	data := block.Data.Data
	if len(txsFilter) != len(block.Data.Data) {
		return nil, errors.Errorf("block data size(%d) is different from Tx filter size(%d)", len(block.Data.Data), len(txsFilter))
	}

	for seqInBlock, txEnvBytes := range data {
		invalid := txsFilter[seqInBlock] != uint8(peer.TxValidationCode_VALID)
		txInfo, err := getTxInfoFromTransactionBytes(txEnvBytes)
		if err != nil {
			continue
		}

		colPvtdataInfo := []*ledger.CollectionPvtdataInfo{}
		for _, ns := range txInfo.txRWSet.NsRwSets {
			for _, hashedCollection := range ns.CollHashedRwSets {
				// skip if no writes

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Use a full block produced by the ordering service including all standard metadata entries
  2. Regenerate/repair the block with proper Metadata (esp. the TRANSACTIONS_FILTER entry)
  3. Update tooling/versions so block generation matches the fabric proto expectations
  4. In tests, populate block.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER]

Example fix

// before
blk := &common.Block{Header: h, Data: d}
c.StoreBlock(blk, nil)
// after
blk.Metadata = &common.BlockMetadata{
    Metadata: make([][]byte, int(common.BlockMetadataIndex_TRANSACTIONS_FILTER)+1),
}
blk.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER] =
    bytes.Repeat([]byte{byte(peer.TxValidationCode_VALID)}, len(d.Data))
c.StoreBlock(blk, nil)
Defensive patterns

Strategy: validation

Validate before calling

func blockHasTxFilter(b *common.Block) bool {
    return b.Metadata != nil &&
        len(b.Metadata.Metadata) > int(common.BlockMetadataIndex_TRANSACTIONS_FILTER)
}
if !blockHasTxFilter(block) {
    return errors.New("block lacks Tx filter metadata")
}

Type guard

func hasTxFilterMetadata(b *common.Block) bool {
    return b != nil && b.Metadata != nil &&
        len(b.Metadata.Metadata) > int(common.BlockMetadataIndex_TRANSACTIONS_FILTER) &&
        len(b.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER]) > 0
}

Prevention

When it happens

Trigger: StoreBlock -> getTxPvtdataInfoFromBlock called with a block whose Metadata is nil or whose Metadata.Metadata slice has length <= BlockMetadataIndex_TRANSACTIONS_FILTER (index 2).

Common situations: Blocks produced by non-Fabric tooling or older/different fabric versions lacking the Tx filter metadata; hand-crafted test blocks without Metadata; corrupted blocks fetched from a misbehaving source.

Related errors


AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04). Data as JSON: /api/errors/8308150534e30929. Report an issue: GitHub.