hyperledger/fabric · error · VSCCEndorsementPolicyError
GetChaincodeDeploymentSpec error %s
Error message
GetChaincodeDeploymentSpec error %s
What it means
VSCC's ValidateLSCCInvocation wraps the error from protoutil.UnmarshalChaincodeDeploymentSpec when parsing the second argument of an lscc transaction. The chaincode deployment spec bytes supplied in the LSCC invocation could not be deserialized into a pb.ChaincodeDeploymentSpec, so validation fails with a policy error (the transaction is marked invalid).
Source
Thrown at core/handlers/validation/builtin/v12/validation_logic.go:529
logger.Debugf("VSCC info: ValidateLSCCInvocation acting on %s %#v", lsccFunc, lsccArgs)
switch lsccFunc {
case lscc.UPGRADE, lscc.DEPLOY:
logger.Debugf("VSCC info: validating invocation of lscc function %s on arguments %#v", lsccFunc, lsccArgs)
if len(lsccArgs) < 2 {
return policyErr(fmt.Errorf("Wrong number of arguments for invocation lscc(%s): expected at least 2, received %d", lsccFunc, len(lsccArgs)))
}
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))View on GitHub (pinned to 2736b63f8f)
Solutions
- Verify the transaction's second lscc argument is created via proto marshaling of ChaincodeDeploymentSpec (e.g. utils.Marshal or protoutil), not JSON or raw bytes.
- Check SDK and peer Fabric versions align (v1.x proto definitions) and regenerate the payload with a matching protobuf runtime.
- Re-inspect the original proposal payload for corruption/truncation in transit; re-submit the deploy transaction.
Example fix
// before: passing a JSON-marshaled spec
args[1], _ := json.Marshal(deploySpec)
// after: proto-marshal the deployment spec
args[1], err := protoutil.Marshal(deploySpec)
if err != nil { return err } Defensive patterns
Strategy: validation
Validate before calling
// client-side pre-check before submitting the lscc tx
specBytes := args[1]
var cds pb.ChaincodeDeploymentSpec
if len(specBytes) == 0 || proto.Unmarshal(specBytes, &cds) != nil || cds.ChaincodeSpec == nil {
return errors.New("lscc arg[1] is not a valid ChaincodeDeploymentSpec")
} Type guard
func isValidCDSEntry(b []byte) bool {
var cds pb.ChaincodeDeploymentSpec
return len(b) > 0 && proto.Unmarshal(b, &cds) == nil && cds.ChaincodeSpec != nil
} Try / catch
spec, err := protoutil.UnmarshalChaincodeDeploymentSpec(args[1])
if err != nil {
logger.Warnf("malformed deployment spec, tx will be invalid: %v", err)
return err
} Prevention
- Always proto-marshal the ChaincodeDeploymentSpec (never JSON or manual byte packing).
- Add a local unmarshal dry-run in deploy scripts before submitting.
- Keep client protobuf definitions in sync with the peer's Fabric version.
When it happens
Trigger: A transaction invoking lscc (deploy/upgrade) carries lsccArgs[1] that is not a valid serialized ChaincodeDeploymentSpec proto: empty bytes, truncated buffer, corrupted payload, or bytes produced by a non-protobuf encoder.
Common situations: Hand-crafted deploy transactions (SDK or CLI misuse), payloads mangled by an intermediary or proxy, Fabric SDK/proto version mismatch producing an incompatible serialization, or fuzzed/malicious transactions rejected during block validation.
Understand the failure class
Background: "cannot parse invalid wire-format data", "cannot unmarshal", "failed unmarshalling": protobuf unmarshal errors explained — this error's family across 10 libraries.
Related errors
- GetChaincodeAction error %s
- invalid key for the collection of chaincode %s:%s; expected
- collection configuration arguments supplied for chaincode %s
- VSCC error: invocation of lscc(%s) does not have appropriate
- unexpected chaincode spec type: %s
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/3db18fa3fff032ca.
Report an issue: GitHub.