{"record":{"id":"cc423cc88f64fd91","repo":"hyperledger/fabric","slug":"duplicate-namespace-s-in-txrwset-cc423c","errorCode":null,"errorMessage":"duplicate namespace '%s' in txRWSet","messagePattern":"duplicate namespace '(.+?)' in txRWSet","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/committer/txvalidator/v20/plugindispatcher/dispatcher.go","lineNumber":177,"sourceCode":"\twrNamespace := map[string]bool{}\n\twrNamespace[ccID] = true\n\tif respPayload.Events != nil {\n\t\tccEvent := &peer.ChaincodeEvent{}\n\t\tif err = proto.Unmarshal(respPayload.Events, ccEvent); err != nil {\n\t\t\treturn peer.TxValidationCode_INVALID_OTHER_REASON, errors.Wrapf(err, \"invalid chaincode event\")\n\t\t}\n\t\tif ccEvent.ChaincodeId != ccID {\n\t\t\treturn peer.TxValidationCode_INVALID_OTHER_REASON, errors.Errorf(\"chaincode event chaincode id does not match chaincode action chaincode id\")\n\t\t}\n\t}\n\n\tnamespaces := make(map[string]struct{})\n\tfor _, ns := range txRWSet.NsRwSets {\n\t\t// check to make sure there is no duplicate namespace in txRWSet\n\t\tif _, ok := namespaces[ns.NameSpace]; ok {\n\t\t\tlogger.Errorf(\"duplicate namespace '%s' in txRWSet\", ns.NameSpace)\n\t\t\treturn peer.TxValidationCode_ILLEGAL_WRITESET,\n\t\t\t\terrors.Errorf(\"duplicate namespace '%s' in txRWSet\", ns.NameSpace)\n\t\t}\n\t\tnamespaces[ns.NameSpace] = struct{}{}\n\n\t\tif v.txWritesToNamespace(ns) {\n\t\t\twrNamespace[ns.NameSpace] = true\n\t\t}\n\t}\n\n\t// we've gathered all the info required to proceed to validation;\n\t// validation will behave differently depending on the chaincode\n\n\t// validate *EACH* read write set according to its chaincode's endorsement policy\n\tfor ns := range wrNamespace {\n\t\t// Get latest chaincode validation plugin name and policy\n\t\tvalidationPlugin, args, err := v.GetInfoForValidate(chdr, ns)\n\t\tif err != nil {\n\t\t\tlogger.Errorf(\"GetInfoForValidate for txId = %s returned error: %+v\", chdr.TxId, err)\n\t\t\treturn peer.TxValidationCode_INVALID_CHAINCODE, err","sourceCodeStart":159,"sourceCodeEnd":195,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/committer/txvalidator/v20/plugindispatcher/dispatcher.go#L159-L195","documentation":"Dispatch found the same namespace appearing more than once in the transaction's NsRwSets. Duplicate namespaces would double-count reads/writes, so Fabric rejects the tx with TxValidationCode_ILLEGAL_WRITESET. This indicates a corrupted or maliciously crafted read-write set.","triggerScenarios":"txRWSet.NsRwSets contains two entries with the same NameSpace for one transaction — malformed rwset assembly by a custom endorser/plugin, or rwsets merged/concatenated incorrectly by client or tooling.","commonSituations":"Custom code that concatenates multiple proposal responses' rwsets without merging by namespace; buggy third-party validation plugins building txRWSet manually; corrupted serialized transactions.","solutions":["Merge read-write sets per namespace (union reads/writes) before building the txrwset instead of appending duplicate NsRwSets entries.","Check any custom endorser or rwset-aggregating tooling for append-without-dedup logic.","Use the standard SDK/endorser path that constructs one NsRwSet per namespace.","Inspect the failing tx's rwset with protos to identify the duplicated namespace and its producer."],"exampleFix":"// before\nrwSet.NsRwSets = append(rwSet.NsRwSets, nsA, nsA)\n// after\nif _, ok := seen[nsA.NameSpace]; !ok { rwSet.NsRwSets = append(rwSet.NsRwSets, nsA); seen[nsA.NameSpace] = true }","handlingStrategy":"validation","validationCode":"const seen = new Set(); for (const ns of rwSet.nsRwSets) { if (seen.has(ns.nameSpace)) throw new Error(`duplicate namespace ${ns.nameSpace}`); seen.add(ns.nameSpace); }","typeGuard":null,"tryCatchPattern":"try { validate(tx); } catch (err) { if (/duplicate namespace/.test(err.message)) { /* merge rwsets by namespace and rebuild tx */ } else { throw err; } }","preventionTips":["Merge rwsets per namespace instead of appending.","Avoid custom rwset aggregation code.","Use the standard endorser path to build transactions.","Decode and inspect rwsets in tooling before submission."],"tags":["hyperledger-fabric","validation","read-write-set"],"backgroundTag":"duplicate-namespace-rwset","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"}