hyperledger/fabric · error

was not able to retrieve private data from transient store,

Error message

was not able to retrieve private data from transient store, namespace <%s>, collection name %s, txID <%s>, due to <%s>

What it means

fromTransientStore reads private write sets pending commit from the transient store via store.GetTxPvtRWSetByTxid. If the transient store iterator creation fails, the error wraps the store's cause with namespace, collection and txID context. This is a storage-layer failure while resolving a gossip pull request before block commit.

Source

Thrown at gossip/privdata/dataretriever.go:177

		}
		pvtRWSetWithConfig.CollectionConfig = configs
		results[common.DigKey{
			Namespace:  dig.Namespace,
			Collection: dig.Collection,
			TxId:       dig.TxId,
			BlockSeq:   dig.BlockSeq,
			SeqInBlock: dig.SeqInBlock,
		}] = pvtRWSetWithConfig
	}

	return results, nil
}

func (dr *dataRetriever) fromTransientStore(dig *protosgossip.PvtDataDigest, filter map[string]ledger.PvtCollFilter) (*util.PrivateRWSetWithConfig, error) {
	results := &util.PrivateRWSetWithConfig{}
	it, err := dr.store.GetTxPvtRWSetByTxid(dig.TxId, filter)
	if err != nil {
		return nil, errors.Errorf("was not able to retrieve private data from transient store, namespace <%s>"+
			", collection name %s, txID <%s>, due to <%s>", dig.Namespace, dig.Collection, dig.TxId, err)
	}
	defer it.Close()

	maxEndorsedAt := uint64(0)
	for {
		res, err := it.Next()
		if err != nil {
			return nil, errors.Errorf("error getting next element out of private data iterator, namespace <%s>"+
				", collection name <%s>, txID <%s>, due to <%s>", dig.Namespace, dig.Collection, dig.TxId, err)
		}
		if res == nil {
			return results, nil
		}
		rws := res.PvtSimulationResultsWithConfig
		if rws == nil {
			dr.logger.Debug("Skipping nil PvtSimulationResultsWithConfig received at block height", res.ReceivedAtBlockHeight)
			continue

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Check the wrapped error and the transient store directory for disk or permission problems.
  2. Restart the peer to reopen the transient store cleanly.
  3. If transient data was lost, re-drive the transaction endorsement or fetch pvt data via reconciliation from other peers.
  4. Monitor transient store disk usage; a full disk causes leveldb write/read failures.

Example fix

// before
it, err := dr.store.GetTxPvtRWSetByTxid(dig.TxId, filter)

// after: treat as recoverable so gossip can retry later
it, err := dr.store.GetTxPvtRWSetByTxid(dig.TxId, filter)
if err != nil {
    logger.Warningf("transient store unavailable for %s, will retry: %v", dig.TxId, err)
    return nil, nil
}
Defensive patterns

Strategy: retry

Validate before calling

if _, err := os.Stat(transientStorePath); err != nil {
    return errors.Wrap(err, "transient store path inaccessible")
}
// ensure the tx exists before reading
if !transientStoreHasTxid(store, txid) {
    return errors.New("tx not in transient store")
}

Type guard

func transientStoreReadable(s store.Store) bool {
    it, err := s.GetTxPvtRWSetByTxid("__probe__", nil)
    if err != nil {
        return false
    }
    it.Close()
    return true
}

Try / catch

it, err := dr.store.GetTxPvtRWSetByTxid(dig.TxId, filter)
if err != nil {
    logger.Warningf("transient store read failed for %s (%v); gossip will retry", dig.TxId, err)
    scheduleRetry()
    return
}
defer it.Close()

Prevention

When it happens

Trigger: GetTxPvtRWSetByTxid(dig.TxId, filter) errors — transient store DB (leveldb) failure, store closed during peer shutdown, or corrupted transient data files.

Common situations: Disk I/O errors on the transient store directory; peer shutting down/restarting mid-pull; transient store data corrupted after an unclean shutdown; transient data purged while a lookup races the purge.

Related errors


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