hyperledger/fabric · error
LSCC invocation is attempting to write to namespace %s
Error message
LSCC invocation is attempting to write to namespace %s
What it means
An lscc deploy/upgrade transaction may only write to two namespaces: "lscc" itself and the chaincode being deployed/upgraded. Any other namespace with writes indicates the transaction is trying to smuggle in extra ledger mutations, so it is rejected as a policy violation.
Source
Thrown at core/handlers/validation/builtin/v12/validation_logic.go:626
}
// the value must be a ChaincodeData struct
cdRWSet := &ccprovider.ChaincodeData{}
err = proto.Unmarshal(lsccrwset.Writes[0].Value, cdRWSet)
if err != nil {
return policyErr(fmt.Errorf("unmarshalling of ChaincodeData failed, error %s", err))
}
// the chaincode name in the lsccwriteset must match the chaincode name in the deployment spec
if cdRWSet.Name != cdsArgs.ChaincodeSpec.ChaincodeId.Name {
return policyErr(fmt.Errorf("expected cc name %s, found %s", cdsArgs.ChaincodeSpec.ChaincodeId.Name, cdRWSet.Name))
}
// the chaincode version in the lsccwriteset must match the chaincode version in the deployment spec
if cdRWSet.Version != cdsArgs.ChaincodeSpec.ChaincodeId.Version {
return policyErr(fmt.Errorf("expected cc version %s, found %s", cdsArgs.ChaincodeSpec.ChaincodeId.Version, cdRWSet.Version))
}
// it must only write to 2 namespaces: LSCC's and the cc that we are deploying/upgrading
for _, ns := range txRWSet.NsRwSets {
if ns.NameSpace != "lscc" && ns.NameSpace != cdRWSet.Name && len(ns.KvRwSet.Writes) > 0 {
return policyErr(fmt.Errorf("LSCC invocation is attempting to write to namespace %s", ns.NameSpace))
}
}
logger.Debugf("Validating %s for cc %s version %s", lsccFunc, cdRWSet.Name, cdRWSet.Version)
switch lsccFunc {
case lscc.DEPLOY:
/******************************************************************/
/* security check 1 - cc not in the LCCC table of instantiated cc */
/******************************************************************/
if ccExistsOnLedger {
return policyErr(fmt.Errorf("Chaincode %s is already instantiated", cdsArgs.ChaincodeSpec.ChaincodeId.Name))
}
/****************************************************************************/
/* security check 2 - validation of rwset (and of collections if enabled) */
/****************************************************************************/View on GitHub (pinned to 2736b63f8f)
Solutions
- Remove any PutState/DelState calls to other namespaces (e.g. 'lscc', other chaincode ids) from the chaincode's Init/upgrade path.
- Use proper cross-chaincode invocation (InvokeChaincode) instead of direct namespace writes.
- Ensure the rwset is generated from a single simulated transaction, not merged.
- Audit the chaincode's init code with peer's rwset inspection before instantiating.
Example fix
// before
stub.PutState("othercc", key, value) // foreign namespace write
// after
stub.InvokeChaincode("othercc", args, channel) // proper cross-cc call Defensive patterns
Strategy: validation
Validate before calling
for _, ns := range txRWSet.NsRwSets {
if ns.NameSpace != "lscc" && ns.NameSpace != cd.Name && len(ns.KvRwSet.Writes) > 0 {
return fmt.Errorf("chaincode writes to forbidden namespace %q during lscc deploy", ns.NameSpace)
}
} Type guard
func onlyAllowedNamespaces(txRWSet *rwset.TxRwSet, ccName string) bool {
for _, ns := range txRWSet.NsRwSets {
if ns.NameSpace != "lscc" && ns.NameSpace != ccName && len(ns.KvRwSet.Writes) > 0 {
return false
}
}
return true
} Try / catch
if err := submitTx(envelope); err != nil {
if strings.Contains(err.Error(), "attempting to write to namespace") {
// remove foreign PutState calls from the chaincode Init/upgrade path and redeploy
}
} Prevention
- Never call PutState with another chaincode's namespace prefix
- Use InvokeChaincode for cross-chaincode interaction
- Audit chaincode Init for stray writes before instantiating
When it happens
Trigger: txRWSet contains an NsRwSet for a namespace other than lscc or cdRWSet.Name with len(KvRwSet.Writes) > 0 — e.g. the invoking chaincode wrote to another chaincode's keys during the same transaction, or the rwset was merged from multiple transactions.
Common situations: Chaincode implementations that call PutState into foreign namespaces during init; cross-chaincode write attempts without proper cross-chaincode calls; rwset aggregation bugs or malicious transaction crafting.
Related errors
- No read write set for lscc was found
- LSCC must issue at least one single putState upon deploy/upg
- no instantiation policy was specified
- LSCC can only issue a single putState upon upgrade
- LSCC can only issue one or two putState upon deploy
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/6b83463aab9509bc.
Report an issue: GitHub.