{"record":{"id":"ad43c38f054ae5fc","repo":"geektutu/7days-golang","slug":"server-returned-v-ad43c3","errorCode":null,"errorMessage":"server returned: %v","messagePattern":"server returned: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gee-cache/day7-proto-buf/geecache/http.go","lineNumber":127,"sourceCode":"type httpGetter struct {\n\tbaseURL string\n}\n\nfunc (h *httpGetter) Get(in *pb.Request, out *pb.Response) error {\n\tu := fmt.Sprintf(\n\t\t\"%v%v/%v\",\n\t\th.baseURL,\n\t\turl.QueryEscape(in.GetGroup()),\n\t\turl.QueryEscape(in.GetKey()),\n\t)\n\tres, err := http.Get(u)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer res.Body.Close()\n\n\tif res.StatusCode != http.StatusOK {\n\t\treturn fmt.Errorf(\"server returned: %v\", res.Status)\n\t}\n\n\tbytes, err := ioutil.ReadAll(res.Body)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"reading response body: %v\", err)\n\t}\n\n\tif err = proto.Unmarshal(bytes, out); err != nil {\n\t\treturn fmt.Errorf(\"decoding response body: %v\", err)\n\t}\n\n\treturn nil\n}\n\nvar _ PeerGetter = (*httpGetter)(nil)\n","sourceCodeStart":109,"sourceCodeEnd":143,"githubUrl":"https://github.com/geektutu/7days-golang/blob/cf3644382101dc13e7fd92e8f5c66cabc51bcd3b/gee-cache/day7-proto-buf/geecache/http.go#L109-L143","documentation":"In the day7-proto-buf build, httpGetter.Get (returning only error, with the payload going to a proto message out-parameter) rejects any non-200 status from a peer with \"server returned: %v\". The peer's handler may return status codes like 400/500 when it cannot serve the key, and this client turns that into a Go error.","triggerScenarios":"group.Get routed to a peer whose handler writes a non-200 status (e.g. its own 'key is required' 400, internal 500); stale peer registration pointing at a wrong endpoint (404).","commonSituations":"Mixed-version cluster where an older peer returns an unexpected status; peer failing to unmarshal/serve and responding 500; proxy returning 502 when the peer is down.","solutions":["Use the status in the error to locate the failing peer and check its logs","Ensure all nodes run protocol-compatible (day7 protobuf) versions","Verify the peer pool addresses/basePath match the serving handlers","Add failover/retry for transient peer unavailability"],"exampleFix":"// before\n// old day5-style peer in the ring can't answer protobuf requests\n// after\n// register only day7 nodes in the consistent-hash ring and keep versions in sync","handlingStrategy":"fallback","validationCode":"// ensure the peer speaks the day7 protobuf protocol before fetching\n// (version probe or shared build-info endpoint)\nif !peerSupportsProto(peerURL) {\n    return errors.New(\"peer does not support protobuf protocol\")\n}","typeGuard":null,"tryCatchPattern":"err := g.Get(key, &out) // day7 signature: payload into proto out-param\nif err != nil && strings.Contains(err.Error(), \"server returned:\") {\n    log.Printf(\"peer fetch failed: %v; loading locally\", err)\n    return g.getLocally(key) // fall back to local Getter\n}","preventionTips":["Keep the whole ring on the same protocol version (day7 protobuf)","Match basePath registration exactly to what each server mounts","Watch peer 4xx/5xx metrics; alert before callers notice","Graceful degradation: fall back to the local loader on peer errors"],"tags":["network","http","protobuf","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"}