hyperledger/fabric · error

the store is empty

Error message

the store is empty

What it means

GetPvtDataByBlockNum returns this error when the store's isEmpty flag is set, meaning no block has ever been committed to this peer's private data store. There is no private data to serve at all. It is a guard against querying an uninitialized/empty store.

Source

Thrown at core/ledger/pvtdatastorage/store.go:477

// ResetLastUpdatedOldBlocksList removes the `lastUpdatedOldBlocksList` entry from the store
func (s *Store) ResetLastUpdatedOldBlocksList() error {
	batch := s.db.NewUpdateBatch()
	batch.Delete(lastUpdatedOldBlocksKey)
	if err := s.db.WriteBatch(batch, true); err != nil {
		return err
	}
	s.isLastUpdatedOldBlocksSet = false
	return nil
}

// GetPvtDataByBlockNum returns only the pvt data  corresponding to the given block number
// The pvt data is filtered by the list of 'ns/collections' supplied in the filter
// A nil filter does not filter any results
func (s *Store) GetPvtDataByBlockNum(blockNum uint64, filter ledger.PvtNsCollFilter) ([]*ledger.TxPvtData, error) {
	logger.Debugf("Get private data for block [%d], filter=%#v", blockNum, filter)
	if s.isEmpty {
		return nil, errors.New("the store is empty")
	}
	lastCommittedBlock := atomic.LoadUint64(&s.lastCommittedBlock)
	if blockNum > lastCommittedBlock {
		return nil, errors.Errorf("last committed block number [%d] smaller than the requested block number [%d]", lastCommittedBlock, blockNum)
	}
	startKey, endKey := getDataKeysForRangeScanByBlockNum(blockNum)
	logger.Debugf("Querying private data storage for write sets using startKey=%#v, endKey=%#v", startKey, endKey)
	itr, err := s.db.GetIterator(startKey, endKey)
	if err != nil {
		return nil, err
	}
	defer itr.Release()

	var blockPvtdata []*ledger.TxPvtData
	var currentTxNum uint64
	var currentTxWsetAssember *txPvtdataAssembler
	firstItr := true

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Wait until the peer has committed at least one block, then retry the query.
  2. Check peer health/sync status — the peer may still be catching up on the channel.
  3. In tests/tools, commit a block (or initialize lastCommittedBlock) before querying.
  4. If the pvtdata store should not be empty, verify the ledger data directory was not wiped or pointed at the wrong path.

Example fix

// before
pvt, err := store.GetPvtDataByBlockNum(5, nil) // panics into error on empty store
// after
if store.IsEmpty() {
    return nil, fmt.Errorf("peer has no committed blocks yet")
}
pvt, err := store.GetPvtDataByBlockNum(5, nil)
Defensive patterns

Strategy: validation

Validate before calling

if ledgerHeight(peer, channel) == 0 {
    return nil, fmt.Errorf("peer has no committed blocks on channel %s yet", channel)
}
pvt, err := store.GetPvtDataByBlockNum(blockNum, nil)

Try / catch

pvt, err := store.GetPvtDataByBlockNum(blockNum, filter)
if err != nil {
    if err.Error() == "the store is empty" {
        return nil, nil // nothing committed yet; treat as no data
    }
    return nil, err
}

Prevention

When it happens

Trigger: Calling GetPvtDataByBlockNum on a peer whose pvtdata store has zero committed blocks — typically right after channel join, before the first block commit, or on a freshly created ledger.

Common situations: Querying private data immediately after genesis/join before the peer has committed anything; a wipe of the pvtdata directory; tests that build a Store without calling Commit first.

Related errors


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