{"record":{"id":"17d65385656e2127","repo":"hyperledger/fabric","slug":"hash-of-pvt-data-for-collection-s-s-does-not-m","errorCode":null,"errorMessage":"hash of pvt data for collection [%s:%s] does not match with the corresponding hash in the public data. public hash = [%#v], pvt data hash = [%#v]","messagePattern":"hash of pvt data for collection \\[(.+?):(.+?)\\] does not match with the corresponding hash in the public data\\. public hash = \\[%#v\\], pvt data hash = \\[%#v\\]","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/ledger/kvledger/txmgmt/validation/batch_preparer.go","lineNumber":183,"sourceCode":"// TODO for now always return true. Add capability of checking if this data was produced by\n// the validating peer itself during simulation and in that case return false\nfunc requiresPvtdataValidation(tx *ledger.TxPvtData) bool {\n\treturn true\n}\n\n// validatePvtdata returns true if hashes of all the collections writeset present in the pvt data\n// match with the corresponding hashes present in the public read-write set\nfunc validatePvtdata(tx *transaction, pvtdata *ledger.TxPvtData) error {\n\tif pvtdata.WriteSet == nil {\n\t\treturn nil\n\t}\n\n\tfor _, nsPvtdata := range pvtdata.WriteSet.NsPvtRwset {\n\t\tfor _, collPvtdata := range nsPvtdata.CollectionPvtRwset {\n\t\t\tcollPvtdataHash := util.ComputeHash(collPvtdata.Rwset)\n\t\t\thashInPubdata := tx.retrieveHash(nsPvtdata.Namespace, collPvtdata.CollectionName)\n\t\t\tif !bytes.Equal(collPvtdataHash, hashInPubdata) {\n\t\t\t\treturn errors.Errorf(`hash of pvt data for collection [%s:%s] does not match with the corresponding hash in the public data. public hash = [%#v], pvt data hash = [%#v]`,\n\t\t\t\t\tnsPvtdata.Namespace, collPvtdata.CollectionName, hashInPubdata, collPvtdataHash)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n\n// preprocessProtoBlock parses the proto instance of block into 'Block' structure.\n// The returned 'Block' structure contains only transactions that are endorser transactions and are not already marked as invalid\nfunc preprocessProtoBlock(postOrderSimulatorProvider PostOrderSimulatorProvider,\n\tvalidateKVFunc func(key string, value []byte) error,\n\tblk *common.Block, doMVCCValidation bool,\n\tcustomTxProcessors map[common.HeaderType]ledger.CustomTxProcessor,\n) (*block, []*TxStatInfo, error) {\n\tb := &block{num: blk.Header.Number}\n\ttxsStatInfo := []*TxStatInfo{}\n\t// Committer validator has already set validation flags based on well formed tran checks\n\ttxsFilter := txflags.ValidationFlags(blk.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER])","sourceCodeStart":165,"sourceCodeEnd":201,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/ledger/kvledger/txmgmt/validation/batch_preparer.go#L165-L201","documentation":"validatePvtdata compared the hash of a collection's private writeset against the hash committed in the public rwset for that transaction and they differ — the private data being validated does not correspond to what the transaction committed, indicating corruption, wrong data, or a tampering attempt.","triggerScenarios":"Thrown at core/ledger/kvledger/txmgmt/validation/batch_preparer.go:183 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Ensure the pvtdata distributed/collected matches what was endorsed at simulation time","Reconcile private data from endorsing peers and re-validate","Investigate for mismatched collection configs between endorsers and committer"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"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"}