hyperledger/fabric · error · VSCCEndorsementPolicyError

unexpected chaincode spec type: %s

Error message

unexpected chaincode spec type: %s

What it means

VSCC validates that the ChaincodeSpec.Type of the lscc deployment spec is one of GOLANG, NODE, JAVA, or CAR. Any other chaincode language type (or an unset type) in a deploy/upgrade transaction is rejected with this policy error.

Source

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

		if (!ac.PrivateChannelData() && len(lsccArgs) > 5) ||
			(ac.PrivateChannelData() && len(lsccArgs) > 6) {
			return policyErr(fmt.Errorf("Wrong number of arguments for invocation lscc(%s): received %d", lsccFunc, len(lsccArgs)))
		}

		cdsArgs, err := protoutil.UnmarshalChaincodeDeploymentSpec(lsccArgs[1])
		if err != nil {
			return policyErr(fmt.Errorf("GetChaincodeDeploymentSpec error %s", err))
		}

		if cdsArgs == nil || cdsArgs.ChaincodeSpec == nil || cdsArgs.ChaincodeSpec.ChaincodeId == nil ||
			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))

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Set ChaincodeSpec.Type explicitly to GOLANG, NODE, JAVA, or CAR when constructing the ChaincodeDeploymentSpec.
  2. Align peer and SDK Fabric versions so the type value is one this peer's VSCC recognizes.
  3. If using a custom type, port the chaincode to a supported language before deploy.

Example fix

// before
spec := &pb.ChaincodeSpec{} // Type left unset -> UNSPECIFIED
// after
spec := &pb.ChaincodeSpec{Type: pb.ChaincodeSpec_GOLANG, ChaincodeId: ccid, Input: input}
Defensive patterns

Strategy: validation

Validate before calling

t := cds.ChaincodeSpec.Type.String()
if t != "GOLANG" && t != "NODE" && t != "JAVA" && t != "CAR" {
    return fmt.Errorf("unsupported chaincode type %q", t)
}

Type guard

func isSupportedCCType(t pb.ChaincodeSpec_Type) bool {
    switch t {
    case pb.ChaincodeSpec_GOLANG, pb.ChaincodeSpec_NODE, pb.ChaincodeSpec_JAVA, pb.ChaincodeSpec_CAR:
        return true
    }
    return false
}

Try / catch

if !isSupportedCCType(spec.Type) {
    return fmt.Errorf("chaincode type %s not supported by this peer", spec.Type)
}

Prevention

When it happens

Trigger: A deploy/upgrade transaction whose ChaincodeDeploymentSpec.ChaincodeSpec.Type serializes to a type outside {GOLANG, NODE, JAVA, CAR} — e.g. UNSPECIFIED type, or a newer chaincode type unknown to this peer version.

Common situations: SDK defaulting the type incorrectly, a peer on an older Fabric version validating transactions containing a newer chaincode type, or hand-constructed ChaincodeSpec messages with the Type field left unset (UNSPECIFIED).

Related errors


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