hyperledger/fabric · error
error marshaling: proto: Marshal called with nil
Error message
error marshaling: proto: Marshal called with nil
What it means
CreateSignedEnvelopeWithTLSBinding explicitly rejects a dataMsg message that is a typed-nil or otherwise invalid protobuf message before calling proto.Marshal, returning 'error marshaling: proto: Marshal called with nil'. Passing a nil concrete message (e.g. (*common.Payload)(nil)) to proto.Marshal panics or errors, so the library guards and returns this sentinel error instead.
Source
Thrown at protoutil/txutils.go:98
dataMsg proto.Message,
msgVersion int32,
epoch uint64,
tlsCertHash []byte,
) (*common.Envelope, error) {
payloadChannelHeader := MakeChannelHeader(txType, msgVersion, channelID, epoch)
payloadChannelHeader.TlsCertHash = tlsCertHash
var err error
payloadSignatureHeader := &common.SignatureHeader{}
if signer != nil {
payloadSignatureHeader, err = NewSignatureHeader(signer)
if err != nil {
return nil, err
}
}
if !dataMsg.ProtoReflect().IsValid() {
return nil, errors.New("error marshaling: proto: Marshal called with nil")
}
data, err := proto.Marshal(dataMsg)
if err != nil {
return nil, errors.Wrap(err, "error marshaling")
}
paylBytes := MarshalOrPanic(
&common.Payload{
Header: MakePayloadHeader(payloadChannelHeader, payloadSignatureHeader),
Data: data,
},
)
var sig []byte
if signer != nil {
sig, err = signer.Sign(paylBytes)
if err != nil {
return nil, errView on GitHub (pinned to 2736b63f8f)
Solutions
- Check that the message passed to CreateSignedEnvelopeWithTLSBinding is non-nil before calling it
- Audit the code path that produced the message for an unchecked (nil, err) return from a constructor or unmarshal call
- Avoid typed-nil interface pitfalls: return untyped nil on error paths, or check with reflection/is-nil helper
- If the message can legitimately be absent, skip envelope creation instead of marshaling
Example fix
// before
env, _ := protoutil.CreateSignedEnvelopeWithTLSBinding(
common.HeaderType_ENDORSER_TRANSACTION, chID, creator, payload, nil, 0)
// after
if payload == nil {
return nil, fmt.Errorf("payload is nil")
}
env, err := protoutil.CreateSignedEnvelopeWithTLSBinding(
common.HeaderType_ENDORSER_TRANSACTION, chID, creator, payload, nil, 0)
if err != nil {
return nil, err
} Defensive patterns
Strategy: validation
Validate before calling
func marshalGuard(msg proto.Message) error {
if msg == nil || !msg.ProtoReflect().IsValid() {
return fmt.Errorf("message is nil or invalid")
}
return nil
} Type guard
func isNilProtoMsg(m interface{}) bool {
if m == nil { return true }
v := reflect.ValueOf(m)
switch v.Kind() {
case reflect.Ptr, reflect.Interface:
return v.IsNil()
}
return false
} Try / catch
if err := marshalGuard(dataMsg); err != nil {
return nil, err
}
env, err := protoutil.CreateSignedEnvelopeWithTLSBinding(t, chID, signer, dataMsg, tlsCertHash, 0)
if err != nil {
return nil, fmt.Errorf("createSignedEnvelope: %w", err)
} Prevention
- Always check the (msg, err) pair from constructors before passing msg on
- Return untyped nil on error paths to avoid typed-nil interface traps
- Run nil checks in helper wrappers around envelope construction
When it happens
Trigger: Calling CreateSignedEnvelopeWithTLSBinding (or the envelope helpers built on it: SeekInfoBlocksFrom, SeekInfoHeadersFrom, seekHelper, seekLastEnvelope, seekNextEnvelope, createDeliverEnvelope) with a nil typed message, e.g. nil *common.Payload, nil *SeekInfo, or nil *Envelope.
Common situations: A variable holding a typed-nil pointer because an earlier constructor returned (nil, err) and the err wasn't checked; Go interface-holding-typed-nil pitfalls when passing messages through interface{} parameters.
Related errors
- marshal failed: proto: Marshal called with nil
- failed to marshal args
- proto: Marshal called with nil
- error marshaling Response: proto: Marshal called with nil
- error marshaling ChaincodeEvent: proto: Marshal called with
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/22a00be9e8baef83.
Report an issue: GitHub.