hyperledger/fabric · error

server returned: %s

Error message

server returned: %s

What it means

ParseResponse first checks Results[0].GetError(); if the discovery server embedded an error result in the response, it is surfaced verbatim as "server returned: <content>". The actual message text comes from the peer (e.g. access denied, failed to get descriptors), so the root cause is the server-side failure described in e.Content.

Source

Thrown at discovery/cmd/endorsers.go:131

	}

	return pc.parser.ParseResponse(channel, res)
}

// EndorserResponseParser parses endorsement responses from the peer
type EndorserResponseParser struct {
	io.Writer
}

// ParseResponse parses the given response for the given channel
func (parser *EndorserResponseParser) ParseResponse(channel string, res ServiceResponse) error {
	rawResponse := res.Raw()
	if len(rawResponse.Results) == 0 {
		return errors.New("empty results")
	}

	if e := rawResponse.Results[0].GetError(); e != nil {
		return errors.Errorf("server returned: %s", e.Content)
	}

	ccQueryRes := rawResponse.Results[0].GetCcQueryRes()
	if ccQueryRes == nil {
		return errors.Errorf("server returned response of unexpected type: %v", reflect.TypeFor[*discovery.QueryResult]())
	}

	jsonBytes, _ := json.MarshalIndent(parseEndorsementDescriptors(ccQueryRes.Content), "", "\t")
	fmt.Fprintln(parser.Writer, string(jsonBytes))
	return nil
}

type chaincodesAndCollections struct {
	Chaincodes  *[]string
	Collections *map[string]string
	NoPrivReads *[]string
}

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Read the e.Content text in the error — it names the actual server-side cause
  2. Verify the client identity is authorized on the channel and the channel exists
  3. Check peer logs for the corresponding discovery service error
  4. Ensure TLS configuration matches between client and peer
Defensive patterns

Strategy: try-catch

Validate before calling

raw := res.Raw()
if len(raw.Results) > 0 {
    if e := raw.Results[0].GetError(); e != nil {
        log.Printf("discovery server error: %s", e.Content)
    }
}

Type guard

func isServerError(res discovery.ServiceResponse) (string, bool) {
    raw := res.Raw()
    if len(raw.Results) == 0 {
        return "", false
    }
    if e := raw.Results[0].GetError(); e != nil {
        return e.Content, true
    }
    return "", false
}

Try / catch

if err := parser.ParseResponse(channel, res); err != nil {
    var srvErr string
    if strings.HasPrefix(err.Error(), "server returned:") {
        srvErr = strings.TrimPrefix(err.Error(), "server returned: ")
        return fmt.Errorf("discovery failed on peer, server said: %s", srvErr)
    }
    return err
}

Prevention

When it happens

Trigger: Server adds a discovery.Error result to the response — e.g. the client is not authorized for the channel, the channel doesn't exist, or the server failed computing endorsement descriptors.

Common situations: Client TLS/identity not enrolled or authorized on the channel; channel name typo'd so the peer can't find it; peer-side failures building endorsement descriptors (e.g. chaincode not installed).

Related errors


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