hyperledger/fabric · error
proto: Marshal called with nil
Error message
proto: Marshal called with nil
What it means
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.
Source
Thrown at core/dispatcher/protobuf.go:27
import (
"github.com/pkg/errors"
"google.golang.org/protobuf/proto"
)
// Protobuf defines the subset of protobuf lifecycle needs and allows
// for injection of mocked marshaling errors.
type Protobuf interface {
Marshal(msg proto.Message) (marshaled []byte, err error)
Unmarshal(marshaled []byte, msg proto.Message) error
}
// ProtobufImpl is the standard implementation to use for Protobuf
type ProtobufImpl struct{}
// Marshal passes through to proto.Marshal
func (p ProtobufImpl) Marshal(msg proto.Message) ([]byte, error) {
if !msg.ProtoReflect().IsValid() {
return nil, errors.New("proto: Marshal called with nil")
}
res, err := proto.Marshal(msg)
return res, errors.WithStack(err)
}
// Unmarshal passes through to proto.Unmarshal
func (p ProtobufImpl) Unmarshal(marshaled []byte, msg proto.Message) error {
return errors.WithStack(proto.Unmarshal(marshaled, msg))
}
View on GitHub (pinned to 2736b63f8f)
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
Example fix
// before
res, err := d.Protobuf.Marshal(outputMsg)
// after
if outputMsg == nil || !outputMsg.ProtoReflect().IsValid() {
return nil, errors.New("output message is nil")
}
res, err := d.Protobuf.Marshal(outputMsg) Defensive patterns
Strategy: validation
Validate before calling
if msg == nil || !msg.ProtoReflect().IsValid() {
return errors.New("cannot marshal nil proto message")
} Type guard
func isValidMessage(m proto.Message) bool {
return m != nil && m.ProtoReflect().IsValid()
} Try / catch
res, err := p.Marshal(msg)
if err != nil {
if strings.Contains(err.Error(), "Marshal called with nil") {
// handle nil-message case
}
return err
} Prevention
- 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
When it happens
Trigger: Calling ProtobufImpl.Marshal (directly, or indirectly via dispatcher.Dispatch marshaling the output message) with a nil or invalid proto message.
Common situations: 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.
Related errors
- proto: Marshal called with nil
- error marshaling SignatureHeader: proto: Marshal called with
- error marshaling
- error marshaling computed config update
- unexpected error while marshaling TxIDIndexValProto message
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/47ae92abdea3e2d7.
Report an issue: GitHub.