hyperledger/fabric · error
invalid message for creating lifecycle chaincode proposal
Error message
invalid message for creating lifecycle chaincode proposal
What it means
createProposalFromCDS builds an install/deploy/upgrade proposal from a ChaincodeDeploymentSpec. For deploy/upgrade proposal types the message argument must be a non-nil *peer.ChaincodeDeploymentSpec; if the type assertion fails or the value is nil, the function refuses to serialize garbage into a proposal and returns this error.
Source
Thrown at protoutil/proputils.go:361
var ccinp *peer.ChaincodeInput
var b []byte
var err error
if msg != nil {
if !msg.ProtoReflect().IsValid() {
return nil, "", errors.New("proto: Marshal called with nil")
}
b, err = proto.Marshal(msg)
if err != nil {
return nil, "", err
}
}
switch propType {
case "deploy":
fallthrough
case "upgrade":
cds, ok := msg.(*peer.ChaincodeDeploymentSpec)
if !ok || cds == nil {
return nil, "", errors.New("invalid message for creating lifecycle chaincode proposal")
}
Args := [][]byte{[]byte(propType), []byte(channelID), b}
Args = append(Args, args...)
ccinp = &peer.ChaincodeInput{Args: Args}
case "install":
ccinp = &peer.ChaincodeInput{Args: [][]byte{[]byte(propType), b}}
}
// wrap the deployment in an invocation spec to lscc...
lsccSpec := &peer.ChaincodeInvocationSpec{
ChaincodeSpec: &peer.ChaincodeSpec{
Type: peer.ChaincodeSpec_GOLANG,
ChaincodeId: &peer.ChaincodeID{Name: "lscc"},
Input: ccinp,
},
}
View on GitHub (pinned to 2736b63f8f)
Solutions
- Ensure the message passed is a fully populated *peer.ChaincodeDeploymentSpec (with ChaincodeSpec.ChaincodeId set and CodePackage/GolangProgram populated as needed).
- Check that you are calling the right helper: install takes the CDS, deploy/upgrade take (CDS, channelID); don't pass a ChaincodeSpec or ChaincodeInput.
- Verify upstream parsing (e.g. utils.UnmarshalCDS / GetChaincodeDeploymentSpec) actually succeeded before building the proposal; handle its error instead of forwarding a nil spec.
- If upgrading code from an older fabric release, confirm the proposal-construction helper names and expected message types still match; the lifecycle v2 path uses _lifecycle APIs instead.
Example fix
// before
prop, _, err := protoutil.CreateDeployProposalFromCDS(chID, spec, signerCert, nil)
// where spec was a *peer.ChaincodeSpec
// after
cds, err := utils.GetChaincodeDeploymentSpec(codePackageBytes, true)
if err != nil {
return err
}
prop, _, err := protoutil.CreateDeployProposalFromCDS(chID, cds, signerCert, nil) Defensive patterns
Strategy: validation
Validate before calling
func validCDS(msg proto.Message) bool {
cds, ok := msg.(*peer.ChaincodeDeploymentSpec)
return ok && cds != nil && cds.ChaincodeSpec != nil && cds.ChaincodeSpec.ChaincodeId != nil
}
if !validCDS(msg) {
return errors.New("caller must pass a populated *peer.ChaincodeDeploymentSpec")
} Type guard
func asCDS(msg interface{}) (*peer.ChaincodeDeploymentSpec, bool) {
cds, ok := msg.(*peer.ChaincodeDeploymentSpec)
return cds, ok && cds != nil
} Try / catch
prop, txid, err := protoutil.CreateDeployProposalFromCDS(chID, cds, signerCert, nil)
if err != nil {
if err.Error() == "invalid message for creating lifecycle chaincode proposal" {
return fmt.Errorf("bug: non-CDS message passed to deploy proposal builder: %w", err)
}
return err
} Prevention
- Always build proposals from a CDS obtained via utils.GetChaincodeDeploymentSpec, never from a ChaincodeSpec.
- Nil-check the typed pointer (not just the interface) before calling the proposal builders.
- Unit-test each proposal type (install/deploy/upgrade) with the exact message type it expects.
- On fabric 2.x prefer the _lifecycle package for install/approve/commit flows.
When it happens
Trigger: Calling CreateInstallProposalFromCDS, CreateDeployProposalFromCDS, or CreateUpgradeProposalFromCDS with a msg argument that is not a *peer.ChaincodeDeploymentSpec (e.g. a ChaincodeSpec or raw bytes) or is a nil typed pointer.
Common situations: Passing a ChaincodeSpec instead of a ChaincodeDeploymentSpec after refactoring; constructing the CDS with &peer.ChaincodeDeploymentSpec{} whose fields were never populated from a CDS parsed elsewhere; nil propagation when upstream spec parsing failed silently.
Related errors
- no chaincode name is provided, channel id [%s]
- chaincode spec is nil
- error unmarshalling ChaincodeHeaderExtension
- only applicable for private data
- unknown operation type
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/fd16c95eebd851c4.
Report an issue: GitHub.