hyperledger/fabric · error

expected cc name %s, found %s

Error message

expected cc name %s, found %s

What it means

After successfully unmarshalling ChaincodeData from the lscc write-set, the validator checks that its Name matches the chaincode name in the submitted ChaincodeDeploymentSpec. A mismatch means the lscc rwset records a different chaincode than the one the transaction claims to deploy/upgrade, so the transaction is rejected as a policy violation.

Source

Thrown at core/handlers/validation/builtin/v13/lscc_validation_logic.go:475

			return policyErr(fmt.Errorf("No read write set for lscc was found"))
		}
		// there must be at least one write
		if len(lsccrwset.Writes) < 1 {
			return policyErr(fmt.Errorf("LSCC must issue at least one single putState upon deploy/upgrade"))
		}
		// the first key name must be the chaincode id provided in the deployment spec
		if lsccrwset.Writes[0].Key != cdsArgs.ChaincodeSpec.ChaincodeId.Name {
			return policyErr(fmt.Errorf("expected key %s, found %s", cdsArgs.ChaincodeSpec.ChaincodeId.Name, lsccrwset.Writes[0].Key))
		}
		// 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:

			/******************************************************************/

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Rebuild the deploy/upgrade proposal with the SDK/lifecycle tooling so ChaincodeData.Name is generated from ChaincodeSpec.ChaincodeId.Name.
  2. If using custom tooling, ensure the ChaincodeData written by lscc uses exactly the ChaincodeId.Name from the proposal.
  3. Do not reuse cached/pre-serialized ChaincodeData across different chaincode deployments.
  4. Confirm you are not replaying a proposal captured for another chaincode or channel.

Example fix

// before: stale data blob from another cc
cd.Name = "oldcc"
// after: derive from the deployment spec
cd := &ccprovider.ChaincodeData{Name: cds.ChaincodeSpec.ChaincodeId.Name, Version: cds.ChaincodeSpec.ChaincodeId.Version, ...}
Defensive patterns

Strategy: validation

Validate before calling

// before submit: ensure lscc ChaincodeData name matches the spec
cd := &ccprovider.ChaincodeData{}
proto.Unmarshal(lsccWriteValue, cd)
if cd.Name != cds.ChaincodeSpec.ChaincodeId.Name {
    return fmt.Errorf("proposal name %s != lscc record name %s", cds.ChaincodeSpec.ChaincodeId.Name, cd.Name)
}

Type guard

func nameMatches(cd *ccprovider.ChaincodeData, specName string) bool { return cd != nil && cd.Name == specName }

Try / catch

if err != nil && strings.Contains(err.Error(), "expected cc name") { /* regenerate the deploy/upgrade proposal with correct name */ }

Prevention

When it happens

Trigger: A deploy/upgrade transaction for chaincode A whose lscc write-set value contains ChaincodeData with Name B — typically from a hand-modified proposal, replayed transaction, or tampered rwset.

Common situations: Reusing a serialized ChaincodeData blob from a previous deployment of a different chaincode, custom lifecycle scripts mixing up name fields, replaying an old proposal after renaming the chaincode, malicious transaction tampering.

Related errors


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