hyperledger/fabric · error
duplicate namespace '%s' in txRWSet
Error message
duplicate namespace '%s' in txRWSet
What it means
The transaction's read-write set (TxRwSet) contains two NsRwSets with the same NameSpace. VSCC rejects this as TxValidationCode_ILLEGAL_WRITESET because a well-formed rwset produced by the peer must have unique namespaces; duplicates indicate a tampered or malformed write set.
Source
Thrown at core/committer/txvalidator/v14/vscc_validator.go:136
alwaysEnforceOriginalNamespace := v.cr.Capabilities().V1_2Validation()
if alwaysEnforceOriginalNamespace {
wrNamespace = append(wrNamespace, ccID)
if respPayload.Events != nil {
ccEvent := &peer.ChaincodeEvent{}
if err = proto.Unmarshal(respPayload.Events, ccEvent); err != nil {
return peer.TxValidationCode_INVALID_OTHER_REASON, errors.Wrapf(err, "invalid chaincode event")
}
if ccEvent.ChaincodeId != ccID {
return peer.TxValidationCode_INVALID_OTHER_REASON, errors.Errorf("chaincode event chaincode id does not match chaincode action chaincode id")
}
}
}
namespaces := make(map[string]struct{})
for _, ns := range txRWSet.NsRwSets {
// check to make sure there is no duplicate namespace in txRWSet
if _, ok := namespaces[ns.NameSpace]; ok {
return peer.TxValidationCode_ILLEGAL_WRITESET, errors.Errorf("duplicate namespace '%s' in txRWSet", ns.NameSpace)
}
namespaces[ns.NameSpace] = struct{}{}
if !v.txWritesToNamespace(ns) {
continue
}
// Check to make sure we did not already populate this chaincode
// name to avoid checking the same namespace twice
if ns.NameSpace != ccID || !alwaysEnforceOriginalNamespace {
wrNamespace = append(wrNamespace, ns.NameSpace)
}
if !writesToLSCC && ns.NameSpace == "lscc" {
writesToLSCC = true
}
if !writesToNonInvokableSCC && IsSysCCAndNotInvokableCC2CC(ns.NameSpace) {View on GitHub (pinned to 2736b63f8f)
Solutions
- Ensure the rwset comes from real endorsement execution by the peer rather than being assembled or merged client-side.
- If merging rwsets is unavoidable, deduplicate NsRwSets by NameSpace before submission.
- Investigate the submitting client for rwset tampering if duplicates appear without custom tooling.
Example fix
// before: append both rwsets
allNs := append(rwsetA.NsRwSets, rwsetB.NsRwSets...)
// after: dedupe by namespace
seen := map[string]bool{}
for _, ns := range allNs { if seen[ns.NameSpace] { continue }; seen[ns.NameSpace] = true; out = append(out, ns) } Defensive patterns
Strategy: validation
Validate before calling
seen := map[string]struct{}{}
for _, ns := range txRWSet.NsRwSets {
if _, dup := seen[ns.NameSpace]; dup {
return fmt.Errorf("duplicate namespace %q in rwset; rebuild transaction", ns.NameSpace)
}
seen[ns.NameSpace] = struct{}{}
} Type guard
func namespacesUnique(rwset *rwset.TxRwSet) bool {
seen := map[string]struct{}{}
for _, ns := range rwset.NsRwSets {
if _, ok := seen[ns.NameSpace]; ok {
return false
}
seen[ns.NameSpace] = struct{}{}
}
return true
} Try / catch
if err != nil {
return peer.TxValidationCode_ILLEGAL_WRITESET, errors.Errorf("duplicate namespace '%s' in txRWSet", ns.NameSpace)
} Prevention
- Obtain rwsets from real peer endorsement instead of client-side assembly or merging.
- If merging rwsets offline, deduplicate NsRwSets by NameSpace first.
- Test custom endorsement pipelines against the peer validator before production.
When it happens
Trigger: A transaction whose Results bytes in the ChaincodeAction decode to a TxRwSet with repeated namespace entries — produced by custom rwset assembly, merging of rwsets without deduplication, or malicious construction.
Common situations: Offline endorsement / custom rwset-building tools concatenating per-chaincode rwsets; chaincode-side or middleware-side rwset manipulation; corruption in crafted transactions for testing.
Related errors
- chaincode %s attempted to write to the namespace of LSCC
- error unmarshalling ChaincodeHeaderExtension
- nil ChaincodeId in header extension
- nil ChaincodeId in ChaincodeAction
- invalid chaincode ID
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/ef2c37c945ea5e48.
Report an issue: GitHub.