{"record":{"id":"06851672b28d204b","repo":"hyperledger/fabric","slug":"server-returned-s","errorCode":null,"errorMessage":"server returned: %s","messagePattern":"server returned: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"discovery/cmd/endorsers.go","lineNumber":131,"sourceCode":"\t}\n\n\treturn pc.parser.ParseResponse(channel, res)\n}\n\n// EndorserResponseParser parses endorsement responses from the peer\ntype EndorserResponseParser struct {\n\tio.Writer\n}\n\n// ParseResponse parses the given response for the given channel\nfunc (parser *EndorserResponseParser) ParseResponse(channel string, res ServiceResponse) error {\n\trawResponse := res.Raw()\n\tif len(rawResponse.Results) == 0 {\n\t\treturn errors.New(\"empty results\")\n\t}\n\n\tif e := rawResponse.Results[0].GetError(); e != nil {\n\t\treturn errors.Errorf(\"server returned: %s\", e.Content)\n\t}\n\n\tccQueryRes := rawResponse.Results[0].GetCcQueryRes()\n\tif ccQueryRes == nil {\n\t\treturn errors.Errorf(\"server returned response of unexpected type: %v\", reflect.TypeFor[*discovery.QueryResult]())\n\t}\n\n\tjsonBytes, _ := json.MarshalIndent(parseEndorsementDescriptors(ccQueryRes.Content), \"\", \"\\t\")\n\tfmt.Fprintln(parser.Writer, string(jsonBytes))\n\treturn nil\n}\n\ntype chaincodesAndCollections struct {\n\tChaincodes  *[]string\n\tCollections *map[string]string\n\tNoPrivReads *[]string\n}\n","sourceCodeStart":113,"sourceCodeEnd":149,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/discovery/cmd/endorsers.go#L113-L149","documentation":"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.","triggerScenarios":"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.","commonSituations":"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).","solutions":["Read the e.Content text in the error — it names the actual server-side cause","Verify the client identity is authorized on the channel and the channel exists","Check peer logs for the corresponding discovery service error","Ensure TLS configuration matches between client and peer"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"raw := res.Raw()\nif len(raw.Results) > 0 {\n    if e := raw.Results[0].GetError(); e != nil {\n        log.Printf(\"discovery server error: %s\", e.Content)\n    }\n}","typeGuard":"func isServerError(res discovery.ServiceResponse) (string, bool) {\n    raw := res.Raw()\n    if len(raw.Results) == 0 {\n        return \"\", false\n    }\n    if e := raw.Results[0].GetError(); e != nil {\n        return e.Content, true\n    }\n    return \"\", false\n}","tryCatchPattern":"if err := parser.ParseResponse(channel, res); err != nil {\n    var srvErr string\n    if strings.HasPrefix(err.Error(), \"server returned:\") {\n        srvErr = strings.TrimPrefix(err.Error(), \"server returned: \")\n        return fmt.Errorf(\"discovery failed on peer, server said: %s\", srvErr)\n    }\n    return err\n}","preventionTips":["Verify client identity enrollment and channel authorization before querying","Match TLS settings between discovery client and peer","Check peer logs whenever this error surfaces — the cause is server-side"],"tags":["go","discovery","server-error","authorization"],"backgroundTag":"server-returned-error","analyzedSha":"2736b63f8fd5932511d56fe68b7039d15977f7f6","analyzedAt":"2026-09-04T08:52:36.465Z","contentChangedAt":"2026-09-04T08:52:36.465Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}