hyperledger/fabric · error · VSCCEndorsementPolicyError

chaincode name '%s' is reserved for system chaincodes

Error message

chaincode name '%s' is reserved for system chaincodes

What it means

VSCC refuses chaincode names that collide with system chaincodes (e.g. lscc, cscc, qscc, escc, vscc). Deploying user chaincode under a reserved name would shadow or confuse system functionality, so the transaction is rejected with a policy error.

Source

Thrown at core/handlers/validation/builtin/v12/validation_logic.go:551

			cap.Action == nil || cap.Action.ProposalResponsePayload == nil {
			return policyErr(fmt.Errorf("VSCC error: invocation of lscc(%s) does not have appropriate arguments", lsccFunc))
		}

		switch cdsArgs.ChaincodeSpec.Type.String() {
		case "GOLANG", "NODE", "JAVA", "CAR":
		default:
			return policyErr(fmt.Errorf("unexpected chaincode spec type: %s", cdsArgs.ChaincodeSpec.Type.String()))
		}

		// validate chaincode name
		ccName := cdsArgs.ChaincodeSpec.ChaincodeId.Name
		// it must comply with the lscc.ChaincodeNameRegExp
		if !lscc.ChaincodeNameRegExp.MatchString(ccName) {
			return policyErr(errors.Errorf("invalid chaincode name '%s'", ccName))
		}
		// it can't match the name of one of the system chaincodes
		if _, in := systemChaincodeNames[ccName]; in {
			return policyErr(errors.Errorf("chaincode name '%s' is reserved for system chaincodes", ccName))
		}

		// validate chaincode version
		ccVersion := cdsArgs.ChaincodeSpec.ChaincodeId.Version
		// it must comply with the lscc.ChaincodeVersionRegExp
		if !lscc.ChaincodeVersionRegExp.MatchString(ccVersion) {
			return policyErr(errors.Errorf("invalid chaincode version '%s'", ccVersion))
		}

		// get the rwset
		pRespPayload, err := protoutil.UnmarshalProposalResponsePayload(cap.Action.ProposalResponsePayload)
		if err != nil {
			return policyErr(fmt.Errorf("GetProposalResponsePayload error %s", err))
		}
		if pRespPayload.Extension == nil {
			return policyErr(fmt.Errorf("nil pRespPayload.Extension"))
		}
		respPayload, err := protoutil.UnmarshalChaincodeAction(pRespPayload.Extension)

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Choose a non-reserved name for your chaincode and redeploy.
  2. Check the peer's systemChaincodeNames list (peer/core.yaml system section) before picking a name.
  3. If you intended to replace a system chaincode, use the chaincode plugin/external builder mechanism instead of deploying under its name.

Example fix

// before
name := "vscc"
// after
name := "myapp-vscc-validator"
Defensive patterns

Strategy: validation

Validate before calling

var systemCCNames = map[string]bool{"lscc": true, "cscc": true, "qscc": true, "escc": true, "vscc": true}
if systemCCNames[ccName] {
    return fmt.Errorf("name %q is reserved for system chaincodes", ccName)
}

Type guard

func isReservedName(name string) bool {
    switch name {
    case "lscc", "cscc", "qscc", "escc", "vscc":
        return true
    }
    return false
}

Try / catch

if isReservedName(name) {
    return fmt.Errorf("cannot deploy user chaincode under reserved name %q", name)
}

Prevention

When it happens

Trigger: A deploy/upgrade transaction whose ChaincodeId.Name equals one of the keys in systemChaincodeNames (such as "lscc", "cscc", "qscc", "vscc", "escc").

Common situations: Developers testing with generic names like "vscc" or "lscc", scripts that default the name to a system chaincode, or typos when overriding system chaincode plugins via config.

Related errors


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