hyperledger/fabric · error
hash of pvt data for collection [%s:%s] does not match with
Error message
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]
What it means
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.
Source
Thrown at core/ledger/kvledger/txmgmt/validation/batch_preparer.go:183
// TODO for now always return true. Add capability of checking if this data was produced by
// the validating peer itself during simulation and in that case return false
func requiresPvtdataValidation(tx *ledger.TxPvtData) bool {
return true
}
// validatePvtdata returns true if hashes of all the collections writeset present in the pvt data
// match with the corresponding hashes present in the public read-write set
func validatePvtdata(tx *transaction, pvtdata *ledger.TxPvtData) error {
if pvtdata.WriteSet == nil {
return nil
}
for _, nsPvtdata := range pvtdata.WriteSet.NsPvtRwset {
for _, collPvtdata := range nsPvtdata.CollectionPvtRwset {
collPvtdataHash := util.ComputeHash(collPvtdata.Rwset)
hashInPubdata := tx.retrieveHash(nsPvtdata.Namespace, collPvtdata.CollectionName)
if !bytes.Equal(collPvtdataHash, hashInPubdata) {
return 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]`,
nsPvtdata.Namespace, collPvtdata.CollectionName, hashInPubdata, collPvtdataHash)
}
}
}
return nil
}
// preprocessProtoBlock parses the proto instance of block into 'Block' structure.
// The returned 'Block' structure contains only transactions that are endorser transactions and are not already marked as invalid
func preprocessProtoBlock(postOrderSimulatorProvider PostOrderSimulatorProvider,
validateKVFunc func(key string, value []byte) error,
blk *common.Block, doMVCCValidation bool,
customTxProcessors map[common.HeaderType]ledger.CustomTxProcessor,
) (*block, []*TxStatInfo, error) {
b := &block{num: blk.Header.Number}
txsStatInfo := []*TxStatInfo{}
// Committer validator has already set validation flags based on well formed tran checks
txsFilter := txflags.ValidationFlags(blk.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER])View on GitHub (pinned to 2736b63f8f)
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
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at core/ledger/kvledger/txmgmt/validation/batch_preparer.go:183 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/17d65385656e2127.
Report an issue: GitHub.