{"record":{"id":"47ae92abdea3e2d7","repo":"hyperledger/fabric","slug":"proto-marshal-called-with-nil-47ae92","errorCode":null,"errorMessage":"proto: Marshal called with nil","messagePattern":"proto: Marshal called with nil","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/dispatcher/protobuf.go","lineNumber":27,"sourceCode":"import (\n\t\"github.com/pkg/errors\"\n\t\"google.golang.org/protobuf/proto\"\n)\n\n// Protobuf defines the subset of protobuf lifecycle needs and allows\n// for injection of mocked marshaling errors.\ntype Protobuf interface {\n\tMarshal(msg proto.Message) (marshaled []byte, err error)\n\tUnmarshal(marshaled []byte, msg proto.Message) error\n}\n\n// ProtobufImpl is the standard implementation to use for Protobuf\ntype ProtobufImpl struct{}\n\n// Marshal passes through to proto.Marshal\nfunc (p ProtobufImpl) Marshal(msg proto.Message) ([]byte, error) {\n\tif !msg.ProtoReflect().IsValid() {\n\t\treturn nil, errors.New(\"proto: Marshal called with nil\")\n\t}\n\tres, err := proto.Marshal(msg)\n\treturn res, errors.WithStack(err)\n}\n\n// Unmarshal passes through to proto.Unmarshal\nfunc (p ProtobufImpl) Unmarshal(marshaled []byte, msg proto.Message) error {\n\treturn errors.WithStack(proto.Unmarshal(marshaled, msg))\n}\n","sourceCodeStart":9,"sourceCodeEnd":37,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/dispatcher/protobuf.go#L9-L37","documentation":"ProtobufImpl.Marshal checks msg.ProtoReflect().IsValid() before calling proto.Marshal. Passing a nil message (a typed-nil or nil interface holding no valid message) makes proto.Marshal fail, so the wrapper returns 'proto: Marshal called with nil' explicitly.","triggerScenarios":"Calling ProtobufImpl.Marshal (directly, or indirectly via dispatcher.Dispatch marshaling the output message) with a nil or invalid proto message.","commonSituations":"Chaincode receiver returned a typed-nil message that slipped past an IsNil check on an interface; marshaling an unset response in tests; a receiver returned a nil pointer of a concrete message type.","solutions":["Ensure the caller never produces a nil message (fix the receiver to return a valid message — see error 841)","Check msg != nil and proto validity before calling Marshal","Initialize the message struct before marshaling"],"exampleFix":"// before\nres, err := d.Protobuf.Marshal(outputMsg)\n// after\nif outputMsg == nil || !outputMsg.ProtoReflect().IsValid() {\n    return nil, errors.New(\"output message is nil\")\n}\nres, err := d.Protobuf.Marshal(outputMsg)","handlingStrategy":"validation","validationCode":"if msg == nil || !msg.ProtoReflect().IsValid() {\n    return errors.New(\"cannot marshal nil proto message\")\n}","typeGuard":"func isValidMessage(m proto.Message) bool {\n    return m != nil && m.ProtoReflect().IsValid()\n}","tryCatchPattern":"res, err := p.Marshal(msg)\nif err != nil {\n    if strings.Contains(err.Error(), \"Marshal called with nil\") {\n        // handle nil-message case\n    }\n    return err\n}","preventionTips":["Check message validity before every Marshal call","Ensure upstream producers never emit typed-nil messages","Test marshal paths with empty-but-valid messages, not nil"],"tags":["protobuf","nil-pointer","serialization"],"backgroundTag":"proto-marshal-nil-message","analyzedSha":"2736b63f8fd5932511d56fe68b7039d15977f7f6","analyzedAt":"2026-09-04T08:52:36.465Z","contentChangedAt":"2026-09-04T08:52:36.465Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}