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

  1. Ensure the caller never produces a nil message (fix the receiver to return a valid message — see error 841)
  2. Check msg != nil and proto validity before calling Marshal
  3. 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

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


AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04). Data as JSON: /api/errors/47ae92abdea3e2d7. Report an issue: GitHub.