hyperledger/fabric · error

tx creator does not have write access permission on privated

Error message

tx creator does not have write access permission on privatedata in chaincodeName:%s collectionName: %s

What it means

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.

Source

Thrown at core/chaincode/handler.go:650

func errorIfCreatorHasNoReadPermission(chaincodeName, collection string, txContext *TransactionContext) error {
	rwPermission, err := getReadWritePermission(chaincodeName, collection, txContext)
	if err != nil {
		return err
	}
	if !rwPermission.read {
		return errors.Errorf("tx creator does not have read access permission on privatedata in chaincodeName:%s collectionName: %s",
			chaincodeName, collection)
	}
	return nil
}

func errorIfCreatorHasNoWritePermission(chaincodeName, collection string, txContext *TransactionContext) error {
	rwPermission, err := getReadWritePermission(chaincodeName, collection, txContext)
	if err != nil {
		return err
	}
	if !rwPermission.write {
		return errors.Errorf("tx creator does not have write access permission on privatedata in chaincodeName:%s collectionName: %s",
			chaincodeName, collection)
	}
	return nil
}

func getReadWritePermission(chaincodeName, collection string, txContext *TransactionContext) (*readWritePermission, error) {
	// check to see if read access has already been checked in the scope of this chaincode simulation
	if rwPermission := txContext.CollectionACLCache.get(collection); rwPermission != nil {
		return rwPermission, nil
	}

	cc := privdata.CollectionCriteria{
		Channel:    txContext.ChannelID,
		Namespace:  chaincodeName,
		Collection: collection,
	}

	readP, writeP, err := txContext.CollectionStore.RetrieveReadWritePermission(cc, txContext.SignedProp, txContext.TXSimulator)

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Amend the collection's memberOrgsPolicy to include the writing org and commit the updated collection config with a chaincode upgrade
  2. Perform the write from a transaction whose creator org is in the collection's write policy
  3. Check the client identity's MSP/org is as intended
  4. Align endorsement policy and collection policy so endorsing orgs are write-authorized

Example fix

// before
"memberOrgsPolicy": { "type": "SIGNATURE", "rule": "OR('Org1MSP.peer')" }
// after: allow Org2 writes
"memberOrgsPolicy": { "type": "SIGNATURE", "rule": "OR('Org1MSP.peer', 'Org2MSP.peer')" }
Defensive patterns

Strategy: try-catch

Validate before calling

// ensure endorsing orgs are write-authorized in collections_config.json:
// rule OR('Org1MSP.peer', ...) should cover all endorser orgs

Try / catch

err := stub.PutPrivateData("coll1", key, value)
if err != nil && strings.Contains(err.Error(), "does not have write access permission") {
    return shim.Error("org not authorized to write this collection; update memberOrgsPolicy")
}
if err != nil { return shim.Error(err.Error()) }

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04). Data as JSON: /api/errors/43e0aceb31af5ed9. Report an issue: GitHub.