hyperledger/fabric · error

Sent %d queries but received %d responses back

Error message

Sent %d queries but received %d responses back

What it means

Client.Send in discovery/client/client.go:186 verifies that the number of response Results equals req.lastIndex (the number of queries sent). A mismatch produces errors.Errorf "Sent %d queries but received %d responses back". It guards against a server returning an incomplete or inconsistent response set.

Source

Thrown at discovery/client/client.go:186

	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 {
		return nil, errors.Wrap(err, "discovery service refused our Request")
	}
	if n := len(resp.Results); n != req.lastIndex {
		return nil, errors.Errorf("Sent %d queries but received %d responses back", req.lastIndex, n)
	}
	return req.computeResponse(resp)
}

type resultOrError any

type response map[key]resultOrError

type localResponse struct {
	response
}

func (cr *localResponse) Peers() ([]*Peer, error) {
	return parsePeers(protoext.LocalMembershipQueryType, cr.response, "")
}

type channelResponse struct {
	response

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Create a fresh discovery Request per Send call instead of reusing one
  2. Check client and peer versions for protobuf/discovery compatibility
  3. Inspect the response Results for embedded per-query error results that shrink the result count handling
  4. Retry Send once on mismatch; persistent mismatch indicates a server bug — capture logs and file it

Example fix

// before: reusing request across sends
req.AddConfigQuery("ch1")
client.Send(ctx, req, auth)
client.Send(ctx, req, auth) // lastIndex already > queries sent

// after: fresh request per send
req1 := discovery.NewRequest(); req1.AddConfigQuery("ch1")
client.Send(ctx, req1, auth)
Defensive patterns

Strategy: validation

Validate before calling

if n := len(resp.Results); n != numQueriesSent {
    return fmt.Errorf("discarding response: sent %d queries, got %d results", numQueriesSent, n)
}

Type guard

func responseConsistent(req *discovery.Request, resp *discovery.Response) bool {
    return len(resp.Results) == len(req.Request.Queries)
}

Try / catch

resp, err := client.Send(ctx, req, auth)
if err != nil && strings.Contains(err.Error(), "queries but received") {
    // rebuild a fresh Request and retry once
}

Prevention

When it happens

Trigger: The discovery server returns a response whose Results slice length differs from the number of queries added via Add* calls — e.g. server dropped responses, version mismatch between client/server request handling, or reuse of the same Request object across Sends.

Common situations: Reusing a Request after a previous Send (lastIndex already incremented); peer/SDK protobuf version skew; server-side errors for individual queries being silently omitted rather than reported.

Related errors


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