hyperledger/fabric · error
proto: Marshal called with nil
Error message
proto: Marshal called with nil
What it means
createProposalFromCDS (used by CreateInstallProposalFromCDS, CreateDeployProposalFromCDS, CreateUpgradeProposalFromCDS) pre-checks msg with ProtoReflect().IsValid() and returns 'proto: Marshal called with nil' before invoking proto.Marshal. It guards against nil or invalid protobuf messages being embedded as chaincode input bytes in the proposal.
Source
Thrown at protoutil/proputils.go:348
vscc []byte,
collectionConfig []byte,
) (*peer.Proposal, string, error) {
if collectionConfig == nil {
return createProposalFromCDS(channelID, cds, creator, "upgrade", policy, escc, vscc)
}
return createProposalFromCDS(channelID, cds, creator, "upgrade", policy, escc, vscc, collectionConfig)
}
// createProposalFromCDS returns a deploy or upgrade proposal given a
// serialized identity and a ChaincodeDeploymentSpec
func createProposalFromCDS(channelID string, msg proto.Message, creator []byte, propType string, args ...[]byte) (*peer.Proposal, string, error) {
// in the new mode, cds will be nil, "deploy" and "upgrade" are instantiates.
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}View on GitHub (pinned to 2736b63f8f)
Solutions
- Ensure the ChaincodeInput (cds.Input) is non-nil and populated with Args before calling Create*ProposalFromCDS
- Use proto.Clone/creation helpers that return valid messages; avoid passing typed nil pointers
- Validate with msg.ProtoReflect().IsValid() (or msg != nil for legacy API) at the call site before building the proposal
Example fix
// before
inv, err := protoutil.CreateInstallProposalFromCDS(nil cds, creator) // cds.Input nil
// after
if cds.Input == nil {
cds.Input = &peer.ChaincodeInput{Args: [][]byte{[]byte("install")}}
}
inv, err := protoutil.CreateInstallProposalFromCDS(cds, creator) Defensive patterns
Strategy: type-guard
Validate before calling
func validCDS(cds *peer.ChaincodeDeploymentSpec) error {
if cds == nil || cds.ChaincodeSpec == nil || cds.ChaincodeSpec.ChaincodeId == nil {
return errors.New("CDS incomplete")
}
if cds.Input == nil {
return errors.New("CDS Input (ChaincodeInput) is nil")
}
return nil
} Type guard
func isMarshalable(m proto.Message) bool {
return m != nil && m.ProtoReflect().IsValid()
} Try / catch
prop, _, err := protoutil.CreateInstallProposalFromCDS(cds, creator)
if err != nil {
if strings.Contains(err.Error(), "Marshal called with nil") {
return nil, fmt.Errorf("chaincode input message not initialized: %w", err)
}
return nil, err
} Prevention
- Always populate cds.Input with Args before building install/deploy/upgrade proposals
- After protobuf API migrations, check message validity with ProtoReflect().IsValid()
- Nil-check typed pointer fields (ChaincodeSpec, ChaincodeId, Input) before proposal creation
When it happens
Trigger: Passing a nil msg, or a nil-pointer protobuf message (invalid ProtoReflect state), as the ChaincodeInput/deployment message when building install/deploy/upgrade proposals — e.g. cds.Input never set or a zero-valued pointer typed field.
Common situations: CLI/SDK chaincode install and upgrade flows after a protobuf API migration (github.com/golang/protobuf to google.golang.org/protobuf), where constructing ChaincodeInput changed and left the message nil.
Related errors
- proto: Marshal called with nil
- error marshaling Response: proto: Marshal called with nil
- error marshaling ChaincodeEvent: proto: Marshal called with
- error marshaling ChaincodeActionPayload: proto: Marshal call
- error marshaling ProposalResponse: proto: Marshal called wit
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/aa8471593a59bcb3.
Report an issue: GitHub.