hyperledger/fabric · error
proto: Marshal called with nil
Error message
proto: Marshal called with nil
What it means
RequestInspector.requestIDFromEnvelope rejects a nil *cb.Envelope before calling proto.Marshal, returning the error message 'proto: Marshal called with nil'. The message mimics the proto library's nil-marshal error because marshaling a nil envelope would fail anyway; the guard makes the failure explicit. Callers pass configEnvelope.LastUpdate, which is nil for genesis-style config updates that carry no LastUpdate envelope.
Source
Thrown at orderer/consensus/smartbft/util.go:182
if err := ri.ValidateIdentityStructure(sID); err != nil {
return types.RequestInfo{}, err
}
var preimage []byte
preimage = append(preimage, sigHdr.Nonce...)
preimage = append(preimage, sigHdr.Creator...)
txID := sha256.Sum256(preimage)
clientID := sha256.Sum256(sigHdr.Creator)
return types.RequestInfo{
ID: hex.EncodeToString(txID[:]),
ClientID: hex.EncodeToString(clientID[:]),
}, nil
}
func (ri *RequestInspector) requestIDFromEnvelope(envelope *cb.Envelope) (types.RequestInfo, error) {
if envelope == nil {
return types.RequestInfo{}, errors.New("proto: Marshal called with nil")
}
data, err := proto.Marshal(envelope)
if err != nil {
return types.RequestInfo{}, err
}
req, err := ri.unwrapReqFromEnvelop(envelope)
if err != nil {
return types.RequestInfo{}, err
}
txID := sha256.Sum256(data)
clientID := sha256.Sum256(req.sigHdr.Creator)
return types.RequestInfo{
ID: hex.EncodeToString(txID[:]),
ClientID: hex.EncodeToString(clientID[:]),
}, nil
}View on GitHub (pinned to 2736b63f8f)
Solutions
- Ensure CONFIG requests carry a valid ConfigEnvelope.LastUpdate (built with protoutil.CreateSignedEnvelope with HeaderType_CONFIG) before submitting
- Rebuild the config update with configtxlator/configtxgen so LastUpdate is populated
- Check the caller's log 'can't get request ID' and inspect the envelope payload with configtxlator decode to see if LastUpdate is missing
- For defense in code, verify the envelope is non-nil and its header type is CONFIG before handing raw requests to the RequestInspector
Example fix
// before: passing a config envelope without LastUpdate
reqInfo := ri.RequestID(configTxBytes) // LastUpdate == nil -> error
// after: build the config update with a populated LastUpdate
env, _ := protoutil.CreateSignedEnvelope(cb.HeaderType_CONFIG, channelID, signer, configUpdateEnvelope, 0, 0)
reqInfo := ri.RequestID([]byte{})
_ = env Defensive patterns
Strategy: validation
Validate before calling
func validConfigRequest(env *cb.Envelope) bool {
if env == nil || len(env.Payload) == 0 {
return false
}
p := &cb.Payload{}
if proto.Unmarshal(env.Payload, p) != nil || p.Header == nil {
return false
}
chdr, err := protoutil.UnmarshalChannelHeader(p.Header.ChannelHeader)
return err == nil && chdr.Type == int32(cb.HeaderType_CONFIG)
} Type guard
func isEnvelope(env *cb.Envelope) bool { return env != nil && len(env.Payload) > 0 } Prevention
- Always build CONFIG transactions with protoutil.CreateSignedEnvelope so LastUpdate is populated
- Log RequestID failures (requestInfo empty) at the submission boundary to catch nil envelopes early
- Never pass configEnvelope.LastUpdate directly without checking for nil
When it happens
Trigger: Calling RequestID on a CONFIG-type request whose inner ConfigEnvelope has LastUpdate == nil (e.g. a genesis/config block submission without a last-update envelope), so requestIDFromEnvelope receives a nil envelope.
Common situations: Submitting or replaying config transactions generated by tooling that leaves LastUpdate unset; replaying blocks from another channel or older network format; unit tests passing nil envelopes into RequestInspector.
Related errors
- failed to marshal request envelope: proto: Marshal called wi
- failed to unmarshal BFT metadata configuration
- data unmarshalling error: %s
- invalid consensus type property in config: %v
- invalid options encoded in consensus metadata: %v
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/645780af16db3333.
Report an issue: GitHub.