hyperledger/fabric · error
failed marshaling Request to bytes
Error message
failed marshaling Request to bytes
What it means
Client.Send in discovery/client/client.go:164 clones the Request, attaches the AuthInfo, and proto.Marshal's it before signing. If protobuf marshaling of the request fails, the underlying error is wrapped with 'failed marshaling Request to bytes'. This is rare because discovery Requests are well-formed protobuf messages, but happens if the request contains unmarshalable nested data.
Source
Thrown at discovery/client/client.go:164
return req
}
func (req *Request) addChaincodeQueryMapping(invocationChains []InvocationChain) {
req.invocationChainMapping[req.lastIndex] = invocationChains
}
func (req *Request) addQueryMapping(queryType protoext.QueryType, key string) {
req.queryMapping[queryType][key] = req.lastIndex
req.lastIndex++
}
// Send sends the request and returns the response, or error on failure
func (c *Client) Send(ctx context.Context, req *Request, auth *discovery.AuthInfo) (Response, error) {
reqToBeSent := proto.Clone(req.Request).(*discovery.Request)
reqToBeSent.Authentication = auth
payload, err := proto.Marshal(reqToBeSent)
if err != nil {
return nil, errors.Wrap(err, "failed marshaling Request to bytes")
}
sig, err := c.signRequest(payload)
if err != nil {
return nil, errors.Wrap(err, "failed signing Request")
}
conn, err := c.createConnection()
if err != nil {
return nil, errors.Wrap(err, "failed connecting to discovery service")
}
cl := discovery.NewDiscoveryClient(conn)
resp, err := cl.Discover(ctx, &discovery.SignedRequest{
Payload: payload,
Signature: sig,
})
if err != nil {View on GitHub (pinned to 2736b63f8f)
Solutions
- Build the request only via discovery.NewRequest() and its Add* query methods; never hand-edit the inner proto message
- Verify the discovery client and server use compatible protobuf definitions
- Check the wrapped underlying error for the exact marshal failure
- Recreate the Request object instead of reusing a mutated one
Example fix
// before: mutating the raw proto request
req.Request.Queries[0].ConfigQuery = &discovery.ConfigQuery{Channel: ""}
// after: use the builder API
req := discovery.NewRequest()
req.AddConfigQuery("mychannel") Defensive patterns
Strategy: try-catch
Validate before calling
// Build requests only via discovery.NewRequest() / Add* builders req := discovery.NewRequest() req.AddConfigQuery(channelID)
Try / catch
resp, err := client.Send(ctx, req, auth)
if err != nil {
var wrapped error
if strings.Contains(err.Error(), "failed marshaling Request to bytes") {
wrapped = fmt.Errorf("rebuild request via NewRequest: %w", err)
}
_ = wrapped
} Prevention
- Never mutate the inner proto Request directly
- Keep discovery protobuf versions in sync between client and peer
- Recreate Request objects rather than reusing mutated ones
When it happens
Trigger: Calling Send with a Request built via NewRequest/AddQuery whose nested protobuf content cannot be marshaled (e.g. corrupted AuthInfo or invalid nested message bytes injected programmatically).
Common situations: Manually mutating a discovery.Request's fields with invalid values; embedding oversized or invalid byte fields; protobuf message corruption between versions of the discovery protobuf.
Related errors
- malformed org definition for org: %s
- error encode input
- message of type %s unknown
- error marshaling: proto: Marshal called with nil
- error marshaling
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/a05d61902ee1c71e.
Report an issue: GitHub.