{"record":{"id":"512b79f4f5ab6e54","repo":"hyperledger/fabric","slug":"was-not-able-to-retrieve-private-data-from-transie","errorCode":null,"errorMessage":"was not able to retrieve private data from transient store, namespace <%s>, collection name %s, txID <%s>, due to <%s>","messagePattern":"was not able to retrieve private data from transient store, namespace <(.+?)>, collection name (.+?), txID <(.+?)>, due to <(.+?)>","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gossip/privdata/dataretriever.go","lineNumber":177,"sourceCode":"\t\t}\n\t\tpvtRWSetWithConfig.CollectionConfig = configs\n\t\tresults[common.DigKey{\n\t\t\tNamespace:  dig.Namespace,\n\t\t\tCollection: dig.Collection,\n\t\t\tTxId:       dig.TxId,\n\t\t\tBlockSeq:   dig.BlockSeq,\n\t\t\tSeqInBlock: dig.SeqInBlock,\n\t\t}] = pvtRWSetWithConfig\n\t}\n\n\treturn results, nil\n}\n\nfunc (dr *dataRetriever) fromTransientStore(dig *protosgossip.PvtDataDigest, filter map[string]ledger.PvtCollFilter) (*util.PrivateRWSetWithConfig, error) {\n\tresults := &util.PrivateRWSetWithConfig{}\n\tit, err := dr.store.GetTxPvtRWSetByTxid(dig.TxId, filter)\n\tif err != nil {\n\t\treturn nil, errors.Errorf(\"was not able to retrieve private data from transient store, namespace <%s>\"+\n\t\t\t\", collection name %s, txID <%s>, due to <%s>\", dig.Namespace, dig.Collection, dig.TxId, err)\n\t}\n\tdefer it.Close()\n\n\tmaxEndorsedAt := uint64(0)\n\tfor {\n\t\tres, err := it.Next()\n\t\tif err != nil {\n\t\t\treturn nil, errors.Errorf(\"error getting next element out of private data iterator, namespace <%s>\"+\n\t\t\t\t\", collection name <%s>, txID <%s>, due to <%s>\", dig.Namespace, dig.Collection, dig.TxId, err)\n\t\t}\n\t\tif res == nil {\n\t\t\treturn results, nil\n\t\t}\n\t\trws := res.PvtSimulationResultsWithConfig\n\t\tif rws == nil {\n\t\t\tdr.logger.Debug(\"Skipping nil PvtSimulationResultsWithConfig received at block height\", res.ReceivedAtBlockHeight)\n\t\t\tcontinue","sourceCodeStart":159,"sourceCodeEnd":195,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/gossip/privdata/dataretriever.go#L159-L195","documentation":"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.","triggerScenarios":"GetTxPvtRWSetByTxid(dig.TxId, filter) errors — transient store DB (leveldb) failure, store closed during peer shutdown, or corrupted transient data files.","commonSituations":"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.","solutions":["Check the wrapped error and the transient store directory for disk or permission problems.","Restart the peer to reopen the transient store cleanly.","If transient data was lost, re-drive the transaction endorsement or fetch pvt data via reconciliation from other peers.","Monitor transient store disk usage; a full disk causes leveldb write/read failures."],"exampleFix":"// before\nit, err := dr.store.GetTxPvtRWSetByTxid(dig.TxId, filter)\n\n// after: treat as recoverable so gossip can retry later\nit, err := dr.store.GetTxPvtRWSetByTxid(dig.TxId, filter)\nif err != nil {\n    logger.Warningf(\"transient store unavailable for %s, will retry: %v\", dig.TxId, err)\n    return nil, nil\n}","handlingStrategy":"retry","validationCode":"if _, err := os.Stat(transientStorePath); err != nil {\n    return errors.Wrap(err, \"transient store path inaccessible\")\n}\n// ensure the tx exists before reading\nif !transientStoreHasTxid(store, txid) {\n    return errors.New(\"tx not in transient store\")\n}","typeGuard":"func transientStoreReadable(s store.Store) bool {\n    it, err := s.GetTxPvtRWSetByTxid(\"__probe__\", nil)\n    if err != nil {\n        return false\n    }\n    it.Close()\n    return true\n}","tryCatchPattern":"it, err := dr.store.GetTxPvtRWSetByTxid(dig.TxId, filter)\nif err != nil {\n    logger.Warningf(\"transient store read failed for %s (%v); gossip will retry\", dig.TxId, err)\n    scheduleRetry()\n    return\n}\ndefer it.Close()","preventionTips":["Monitor transient store disk space and I/O health.","Avoid peer shutdown while gossip pulls are in flight (graceful stop).","Treat transient data as ephemeral — rely on reconciliation for durability.","Check permissions on the transient store directory after OS upgrades."],"tags":["fabric","transient-store","gossip","private-data"],"backgroundTag":"transient-store-read-failed","analyzedSha":"2736b63f8fd5932511d56fe68b7039d15977f7f6","analyzedAt":"2026-09-04T08:52:36.465Z","contentChangedAt":"2026-09-04T08:52:36.465Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}