{"record":{"id":"43e0aceb31af5ed9","repo":"hyperledger/fabric","slug":"tx-creator-does-not-have-write-access-permission-o","errorCode":null,"errorMessage":"tx creator does not have write access permission on privatedata in chaincodeName:%s collectionName: %s","messagePattern":"tx creator does not have write access permission on privatedata in chaincodeName:(.+?) collectionName: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/chaincode/handler.go","lineNumber":650,"sourceCode":"func errorIfCreatorHasNoReadPermission(chaincodeName, collection string, txContext *TransactionContext) error {\n\trwPermission, err := getReadWritePermission(chaincodeName, collection, txContext)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif !rwPermission.read {\n\t\treturn errors.Errorf(\"tx creator does not have read access permission on privatedata in chaincodeName:%s collectionName: %s\",\n\t\t\tchaincodeName, collection)\n\t}\n\treturn nil\n}\n\nfunc errorIfCreatorHasNoWritePermission(chaincodeName, collection string, txContext *TransactionContext) error {\n\trwPermission, err := getReadWritePermission(chaincodeName, collection, txContext)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif !rwPermission.write {\n\t\treturn errors.Errorf(\"tx creator does not have write access permission on privatedata in chaincodeName:%s collectionName: %s\",\n\t\t\tchaincodeName, collection)\n\t}\n\treturn nil\n}\n\nfunc getReadWritePermission(chaincodeName, collection string, txContext *TransactionContext) (*readWritePermission, error) {\n\t// check to see if read access has already been checked in the scope of this chaincode simulation\n\tif rwPermission := txContext.CollectionACLCache.get(collection); rwPermission != nil {\n\t\treturn rwPermission, nil\n\t}\n\n\tcc := privdata.CollectionCriteria{\n\t\tChannel:    txContext.ChannelID,\n\t\tNamespace:  chaincodeName,\n\t\tCollection: collection,\n\t}\n\n\treadP, writeP, err := txContext.CollectionStore.RetrieveReadWritePermission(cc, txContext.SignedProp, txContext.TXSimulator)","sourceCodeStart":632,"sourceCodeEnd":668,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/chaincode/handler.go#L632-L668","documentation":"errorIfCreatorHasNoWritePermission enforces that the transaction creator's organization is permitted to WRITE to the private data collection per its memberOrgsPolicy. This error is thrown from putState, putStateMetadata, delState, and purgePrivateData paths when the creator's org is not in the collection's write policy.","triggerScenarios":"Chaincode calls PutPrivateData / PutPrivateDataMetadata / DelPrivateData on a collection whose memberOrgsPolicy does not authorize the tx creator's org to write; endorsing peer rejects the write during simulation.","commonSituations":"Collection write policy narrower than the set of orgs endorsing the chaincode; developers expecting all collection member orgs to have write access when only read is granted; misconfigured client MSP; collection definition changed without recommitting chaincode definition.","solutions":["Amend the collection's memberOrgsPolicy to include the writing org and commit the updated collection config with a chaincode upgrade","Perform the write from a transaction whose creator org is in the collection's write policy","Check the client identity's MSP/org is as intended","Align endorsement policy and collection policy so endorsing orgs are write-authorized"],"exampleFix":"// before\n\"memberOrgsPolicy\": { \"type\": \"SIGNATURE\", \"rule\": \"OR('Org1MSP.peer')\" }\n// after: allow Org2 writes\n\"memberOrgsPolicy\": { \"type\": \"SIGNATURE\", \"rule\": \"OR('Org1MSP.peer', 'Org2MSP.peer')\" }","handlingStrategy":"try-catch","validationCode":"// ensure endorsing orgs are write-authorized in collections_config.json:\n// rule OR('Org1MSP.peer', ...) should cover all endorser orgs","typeGuard":null,"tryCatchPattern":"err := stub.PutPrivateData(\"coll1\", key, value)\nif err != nil && strings.Contains(err.Error(), \"does not have write access permission\") {\n    return shim.Error(\"org not authorized to write this collection; update memberOrgsPolicy\")\n}\nif err != nil { return shim.Error(err.Error()) }","preventionTips":["Align chaincode endorsement policy with the collection write policy","Include write-policy checks in chaincode definition review checklist","Re-commit chaincode definition after any collection policy change","Test writes from each expected org before rollout"],"tags":["hyperledger-fabric","private-data","access-control","collections"],"backgroundTag":"private-data-access-denied","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"}