hyperledger/fabric · error

block hashes not maintained in index

Error message

block hashes not maintained in index

What it means

getBlockLocByHash returns this sentinel error when the block index was configured without IndexableAttrBlockHash, meaning the store never wrote blockHash->location index entries. Retrieving a block by hash is therefore unsupported by the current index configuration; it is not an IO failure but a capability/configuration check via isAttributeIndexed.

Source

Thrown at common/ledger/blkstorage/blockindex.go:156

		}
	}

	batch.Put(indexSavePointKey, encodeBlockNum(blockIdxInfo.blockNum))
	// Setting snyc to true as a precaution, false may be an ok optimization after further testing.
	if err := index.db.WriteBatch(batch, true); err != nil {
		return err
	}
	return nil
}

func (index *blockIndex) isAttributeIndexed(attribute IndexableAttr) bool {
	_, ok := index.indexItemsMap[attribute]
	return ok
}

func (index *blockIndex) getBlockLocByHash(blockHash []byte) (*fileLocPointer, error) {
	if !index.isAttributeIndexed(IndexableAttrBlockHash) {
		return nil, errors.New("block hashes not maintained in index")
	}
	b, err := index.db.Get(constructBlockHashKey(blockHash))
	if err != nil {
		return nil, err
	}
	if b == nil {
		return nil, errors.Errorf("no such block hash [%x] in index", blockHash)
	}
	blkLoc := &fileLocPointer{}
	if err := blkLoc.unmarshal(b); err != nil {
		return nil, err
	}
	return blkLoc, nil
}

func (index *blockIndex) getBlockLocByBlockNum(blockNum uint64) (*fileLocPointer, error) {
	if !index.isAttributeIndexed(IndexableAttrBlockNum) {
		return nil, errors.New("block numbers not maintained in index")

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Enable block-hash indexing: include IndexableAttrBlockHash in the blkstorage index config (ledger.blockIndex or IndexConfig.Attributes) and restart.
  2. If the index was created without it, existing blocks must be re-indexed (syncIndex/index replay) or the ledger re-synced from peers/orderers so the hash entries are written.
  3. Change the application to look up blocks by number or txID instead of hash when hash indexing is intentionally disabled.
  4. Verify the effective ledger config on the running peer (core.yaml ledger -> blockIndex) matches expectations before diagnosing further.

Example fix

// before: core.yaml
ledger:
  blockIndex:
    # hash lookups fail: block hashes not maintained in index
// after: use default (all attributes indexed)
ledger:
  blockIndex:
    maxBatchSize: 10  # omitting index-attr overrides keeps full index incl. block hash
Defensive patterns

Strategy: validation

Validate before calling

// Go: confirm hash indexing is enabled before calling GetBlockByHash
func hashIndexEnabled(cfg blkstorage.IndexConfig) bool {
	for _, a := range cfg.Attributes {
		if a == blkstorage.IndexableAttrBlockHash {
			return true
		}
	}
	return false
}

Try / catch

// Go: fall back to a linear scan by number when hash lookup is unsupported
block, err := store.RetrieveBlockByHash(hash)
if err != nil {
	if strings.Contains(err.Error(), "block hashes not maintained in index") {
		// fall back: iterate RetrieveBlocks and compare Header.DataHash
	} else {
		return err
	}
}

Prevention

When it happens

Trigger: Calling GetBlockByHash (retrieveBlockByHash -> getBlockLocByHash) on a block store whose ledger config omitted blockHash from index items (e.g. IndexConfig.Attributes not including IndexableAttrBlockHash).

Common situations: Deployments that trimmed indexable attributes for performance and later queried by hash; copied ledgersData from an instance configured differently; tests/tools assuming the default full index.

Related errors


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