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

  1. Build the request only via discovery.NewRequest() and its Add* query methods; never hand-edit the inner proto message
  2. Verify the discovery client and server use compatible protobuf definitions
  3. Check the wrapped underlying error for the exact marshal failure
  4. 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

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


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