{"record":{"id":"20cf6aae4edc81db","repo":"hyperledger/fabric","slug":"expected-block-number-d-received-block-number-d","errorCode":null,"errorMessage":"expected block number=%d, received block number=%d","messagePattern":"expected block number=(.+?), received block number=(.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/ledger/pvtdatastorage/store.go","lineNumber":316,"sourceCode":"\t\ts.isLastUpdatedOldBlocksSet = true\n\t} // false if not set\n\n\treturn nil\n}\n\n// Init initializes the store. This function is expected to be invoked before using the store\nfunc (s *Store) Init(btlPolicy pvtdatapolicy.BTLPolicy) {\n\ts.btlPolicy = btlPolicy\n}\n\n// Commit commits the pvt data as well as both the eligible and ineligible\n// missing private data --- `eligible` denotes that the missing private data belongs to a collection\n// for which this peer is a member; `ineligible` denotes that the missing private data belong to a\n// collection for which this peer is not a member.\nfunc (s *Store) Commit(blockNum uint64, pvtData []*ledger.TxPvtData, missingPvtData ledger.TxMissingPvtData, purgeMarkers []*PurgeMarker) error {\n\texpectedBlockNum := s.nextBlockNum()\n\tif expectedBlockNum != blockNum {\n\t\treturn errors.Errorf(\"expected block number=%d, received block number=%d\", expectedBlockNum, blockNum)\n\t}\n\n\tbatch := s.db.NewUpdateBatch()\n\tvar err error\n\tvar key, val []byte\n\n\tstoreEntries, err := prepareStoreEntries(blockNum, pvtData, s.btlPolicy, missingPvtData, purgeMarkers)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tfor _, dataEntry := range storeEntries.dataEntries {\n\t\tkey = encodeDataKey(dataEntry.key)\n\t\tif val, err = encodeDataValue(dataEntry.value); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tbatch.Put(key, val)\n\t}","sourceCodeStart":298,"sourceCodeEnd":334,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/ledger/pvtdatastorage/store.go#L298-L334","documentation":"The private data store Commit() checks that the block being committed matches its internal expected block number (nextBlockNum). If the caller supplies a block number that is not exactly the next sequential one, the store rejects it to keep private-data key ordering consistent with the block store. This indicates out-of-order or duplicate block commits reaching the pvtdata store.","triggerScenarios":"Calling Store.Commit(blockNum, ...) with a blockNum != s.nextBlockNum() — e.g. committing block N+1 before N, re-committing an already-committed block, or resetting one store but not the other so the sequences diverge.","commonSituations":"Ledger rollback/reset applied to the block store but not the private data store (or vice versa); custom ledger implementations committing out of order; concurrent/gossip-driven commit races; restoring from a backup that is offset by one or more blocks.","solutions":["Verify blocks are committed strictly in sequence; check the caller (commitToPvtAndBlockStore) is not skipping or duplicating block numbers.","If the stores diverged, reset both the block store and pvtdata store to the same height (e.g. peer node reset/rollback to a common block).","Check for stale backups: restore block store and pvtdata store snapshots taken at the same block height.","Inspect logs for the expected vs received numbers to determine which store is ahead/behind and resync accordingly."],"exampleFix":"// before\npvtdataStore.Commit(ledger.NextBlockNumber(currentBlockNum)+1, pvtData, missing, purgeMarkers)\n// after\npvtdataStore.Commit(nextExpectedBlockNum, pvtData, missing, purgeMarkers) // must equal store.nextBlockNum()","handlingStrategy":"validation","validationCode":"if blockNum != expectedNextBlockNum(store) {\n    return fmt.Errorf(\"refusing commit: block %d out of sequence, expected %d\", blockNum, expectedNextBlockNum(store))\n}\nerr := store.Commit(blockNum, pvtData, missing, purgeMarkers)","typeGuard":null,"tryCatchPattern":"if err := store.Commit(blockNum, pvtData, missing, purgeMarkers); err != nil {\n    if strings.Contains(err.Error(), \"expected block number\") {\n        // sequence divergence: halt commit pipeline, run ledger reset/rollback to resync\n    }\n    return err\n}","preventionTips":["Commit blocks strictly sequentially through a single commit path/goroutine.","After any peer reset or rollback, reset both block store and pvtdata store to the same height.","Monitor expected vs received block numbers in logs to catch divergence early."],"tags":["ledger","private-data","block-commit","sequence"],"backgroundTag":"block-number-mismatch","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"}