{"record":{"id":"8aee7d515ef0ebec","repo":"geektutu/7days-golang","slug":"server-returned-v","errorCode":null,"errorMessage":"server returned: %v","messagePattern":"server returned: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gee-cache/day5-multi-nodes/geecache/http.go","lineNumber":117,"sourceCode":"type httpGetter struct {\n\tbaseURL string\n}\n\nfunc (h *httpGetter) Get(group string, key string) ([]byte, error) {\n\tu := fmt.Sprintf(\n\t\t\"%v%v/%v\",\n\t\th.baseURL,\n\t\turl.QueryEscape(group),\n\t\turl.QueryEscape(key),\n\t)\n\tres, err := http.Get(u)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer res.Body.Close()\n\n\tif res.StatusCode != http.StatusOK {\n\t\treturn nil, fmt.Errorf(\"server returned: %v\", res.Status)\n\t}\n\n\tbytes, err := ioutil.ReadAll(res.Body)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"reading response body: %v\", err)\n\t}\n\n\treturn bytes, nil\n}\n\nvar _ PeerGetter = (*httpGetter)(nil)\n","sourceCodeStart":99,"sourceCodeEnd":129,"githubUrl":"https://github.com/geektutu/7days-golang/blob/cf3644382101dc13e7fd92e8f5c66cabc51bcd3b/gee-cache/day5-multi-nodes/geecache/http.go#L99-L129","documentation":"The httpGetter peer client checks the HTTP status of the response from a remote gee-cache node and rejects anything other than 200 OK, wrapping the status line (e.g. \"500 Internal Server Error\") in this error. This happens when the remote node's ServeHTTP handler returned an error status — typically because that node failed to load the value, hit its own 'key is required' error, or experienced an internal failure. The error propagates back through GetGroup/Get to the original caller.","triggerScenarios":"Calling group.Get(key) where the consistent-hash ring routes the key to a peer node whose HTTP endpoint answers with 4xx/5xx; peer server crashed mid-request and a proxy returned 502/503; wrong base URL configured in the peer pool causing 404 Not Found.","commonSituations":"A peer node not yet started or listening on a different port than registered; a reverse proxy in front of the node returning 502; the peer's handler returning 500 because its loader/DB failed; mistyped basePath so requests 404.","solutions":["Inspect the wrapped status text in the error to identify which peer and which status; check that peer's logs for the underlying failure","Verify the peer's address and basePath registered in gee-cache's peers/scheduler match the actually running server","Ensure the peer process is healthy (restart it, check its loader dependencies like DB/etcd)","Add retry/failover at the caller if peers can be transiently unavailable"],"exampleFix":"// before\nv, err := group.Get(key) // \"server returned: 404 Not Found\" on bad basePath\n// after\n// register peers with the exact path the server serves:\npeers.Set(baseURL + \"/_geecache/\") // server must mount httpPool.Handler() on the same basePath","handlingStrategy":"retry","validationCode":"// health-check peers before relying on them\nresp, err := http.Get(peerURL + basePath + \"/_health/\")\nif err != nil || resp.StatusCode != http.StatusOK {\n    return errors.New(\"peer unavailable: \" + peerURL)\n}","typeGuard":null,"tryCatchPattern":"v, err := group.Get(key)\nif err != nil {\n    var retriable = strings.Contains(err.Error(), \"server returned: 5\")\n    if retriable {\n        time.Sleep(100 * time.Millisecond)\n        return group.Get(key) // retry, or fall back to local loader\n    }\n    return err\n}","preventionTips":["Keep peer registration (address + basePath) generated from the same config the server binds to","Health-check nodes before adding them to the consistent-hash ring","Monitor peer 5xx rates and remove unhealthy nodes from the ring","Deploy a fallback path (local loader) for peer fetch failures"],"tags":["network","http","distributed-cache","go"],"backgroundTag":"http-5xx-response","analyzedSha":"cf3644382101dc13e7fd92e8f5c66cabc51bcd3b","analyzedAt":"2026-09-03T18:31:24.087Z","contentChangedAt":"2026-09-03T18:31:24.087Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}