hyperledger/fabric · error
server returned response of unexpected type: %v
Error message
server returned response of unexpected type: %v
What it means
ParseResponse expects Results[0] to be a chaincode query result (GetCcQueryRes). If that field is nil — the server returned some other QueryResult type (config, membership, or nil) — the parser rejects it with "server returned response of unexpected type". This is a type-mismatch guard ensuring the response matches the endorsers query that was sent.
Source
Thrown at discovery/cmd/endorsers.go:136
// 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
}
func (ec *chaincodesAndCollections) noPrivateReads(chaincodeName string) bool {
return slices.Contains(*ec.NoPrivReads, chaincodeName)
}
func (ec *chaincodesAndCollections) existsInChaincodes(chaincodeName string) bool {View on GitHub (pinned to 2736b63f8f)
Solutions
- Ensure ParseResponse is called on the response of an AddEndorsersQuery request, not a config/membership query
- Align peer and discovery client/CLI versions
- Inspect the raw response (res.Raw()) to see what result type was actually returned
Example fix
// before res, _ := stub.Send(server, conf, configReq) parser.ParseResponse(channel, res) // config response parsed as endorsers // after res, _ := stub.Send(server, conf, endorsersReq) parser.ParseResponse(channel, res)
Defensive patterns
Strategy: type-guard
Validate before calling
raw := res.Raw()
if len(raw.Results) > 0 && raw.Results[0].GetCcQueryRes() == nil {
return errors.New("response is not a chaincode query result; was this response from an endorsers query?")
} Type guard
func isEndorsersResponse(res discovery.ServiceResponse) bool {
raw := res.Raw()
return len(raw.Results) > 0 && raw.Results[0].GetCcQueryRes() != nil
} Try / catch
if err := parser.ParseResponse(channel, res); err != nil {
if strings.Contains(err.Error(), "unexpected type") {
return fmt.Errorf("response/query mismatch: ensure ParseResponse is paired with AddEndorsersQuery: %w", err)
}
return err
} Prevention
- Pair each response with the parser matching its query type (endorsers vs config vs membership)
- Keep one discovery client version across CLI and application code
- Assert the query type before parsing with GetCcQueryRes != nil
When it happens
Trigger: Sending an endorsers request but receiving a response whose first result is a config query result, membership result, or an unset/nil result — usually from mismatched request/response pairing or a server/client version mismatch.
Common situations: Reusing a response object from a different query type (config/membership) with the endorsers parser; peer version returning a different result schema; mixing discovery client versions between CLI and peer.
Related errors
- empty results
- receiver %T.%s does not return a an implementor of proto.Mes
- expected QueryResult of either ChaincodeQueryResult or Error
- invocation chain should not be empty
- chaincode name should not be empty
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/57c6d15505b7fe80.
Report an issue: GitHub.