{"record":{"id":"7906a38c3090c2e4","repo":"hyperledger/fabric","slug":"wasn-t-able-to-obtain-private-data-block-sequence","errorCode":null,"errorMessage":"wasn't able to obtain private data, block sequence number %d, due to %s","messagePattern":"wasn't able to obtain private data, block sequence number (.+?), due to (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gossip/privdata/dataretriever.go","lineNumber":117,"sourceCode":"\t\treturn results, false, nil\n\t}\n\t// Since ledger height is above block sequence number private data is might be available in the ledger\n\tresults, err := dr.fromLedger(digests, blockNum)\n\treturn results, true, err\n}\n\nfunc (dr *dataRetriever) fromLedger(digests []*protosgossip.PvtDataDigest, blockNum uint64) (Dig2PvtRWSetWithConfig, error) {\n\tfilter := make(map[string]ledger.PvtCollFilter)\n\tfor _, dig := range digests {\n\t\tif _, ok := filter[dig.Namespace]; !ok {\n\t\t\tfilter[dig.Namespace] = make(ledger.PvtCollFilter)\n\t\t}\n\t\tfilter[dig.Namespace][dig.Collection] = true\n\t}\n\n\tpvtData, err := dr.committer.GetPvtDataByNum(blockNum, filter)\n\tif err != nil {\n\t\treturn nil, errors.Errorf(\"wasn't able to obtain private data, block sequence number %d, due to %s\", blockNum, err)\n\t}\n\n\tresults := make(Dig2PvtRWSetWithConfig)\n\tfor _, dig := range digests {\n\t\tpvtRWSetWithConfig := &util.PrivateRWSetWithConfig{}\n\t\tfor _, data := range pvtData {\n\t\t\tif data.WriteSet == nil {\n\t\t\t\tdr.logger.Warning(\"Received nil write set for collection tx in block\", data.SeqInBlock, \"block number\", blockNum)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// private data doesn't hold rwsets for namespace and collection or\n\t\t\t// belongs to different transaction\n\t\t\tif !data.Has(dig.Namespace, dig.Collection) || data.SeqInBlock != dig.SeqInBlock {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tpvtRWSet := dr.extractPvtRWsets(data.WriteSet.NsPvtRwset, dig.Namespace, dig.Collection)","sourceCodeStart":99,"sourceCodeEnd":135,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/gossip/privdata/dataretriever.go#L99-L135","documentation":"fromLedger fetches private data by block number from the ledger via committer.GetPvtDataByNum. When the underlying ledger lookup fails (DB error, block not yet committed, iterator failure), this error reports the block sequence number and the wrapped cause. It is produced on the reconciliation path where the block is expected to exist in the ledger.","triggerScenarios":"GetPvtDataByNum(blockNum, filter) fails: requesting pvt data for a block beyond local ledger height, ledger DB read error, or the pvt-data store hasn't reconciled that block yet.","commonSituations":"Reconciling with a peer that is ahead (local peer behind); pvtdata store pruned by retention policy; corrupted pvtdata index; request arriving before local commit of the block.","solutions":["Wait for the local peer to catch up and commit the block, then retry (gossip reconciliation retries automatically).","Verify the peer's ledger height with `peer channel getinfo` matches the requested blockNum.","Check pvtdata store health and whether retention policies purged the block's private data.","Inspect the wrapped %s cause for a concrete DB error and fix storage-level issues."],"exampleFix":"// before: requesting pvt data for uncommitted block\npvtData, err := dr.committer.GetPvtDataByNum(blockNum, filter) // blockNum >= height\n\n// after: clamp to current height\nheight, _ := dr.committer.LedgerHeight()\nif blockNum >= height {\n    return nil, nil // nothing reconcilable yet\n}\npvtData, err := dr.committer.GetPvtDataByNum(blockNum, filter)","handlingStrategy":"retry","validationCode":"height, err := committer.LedgerHeight()\nif err != nil || blockNum >= height {\n    return errors.New(\"block not committed locally; cannot reconcile yet\")\n}","typeGuard":"func blockAvailable(c privdata.Committer, blockNum uint64) bool {\n    h, err := c.LedgerHeight()\n    return err == nil && blockNum < h\n}","tryCatchPattern":"pvtData, err := dr.committer.GetPvtDataByNum(blockNum, filter)\nif err != nil {\n    logger.Warningf(\"pvt data for seq %d unavailable (%v), scheduling reconciliation retry\", blockNum, err)\n    scheduleRetry(blockNum)\n    return\n}","preventionTips":["Wait for local commit before requesting pvt data by block number.","Verify peer ledger height with `peer channel getinfo` before reconciliation.","Don't prune pvtdata for blocks still needed by peers.","Monitor wrapped errors for DB-level root causes."],"tags":["fabric","ledger","private-data","reconciliation"],"backgroundTag":"pvtdata-block-not-found","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"}