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
- Wait until the peer has committed at least one block, then retry the query.
- Check peer health/sync status — the peer may still be catching up on the channel.
- In tests/tools, commit a block (or initialize lastCommittedBlock) before querying.
- 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
- Check ledger height before querying private data on freshly joined peers.
- Gate queries behind peer-sync health checks after startup or channel join.
- In tests, seed the store with at least one Commit before read paths.
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
- unable to check whether collection existed earlier for chain
- expected block number=%d, received block number=%d
- last committed block number [%d] smaller than the requested
- unexpected call. Boot KV Hashes are persisted only for the d
- error getting private data by block number %d
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/388ae6bf5b686b83.
Report an issue: GitHub.