{"record":{"id":"1e44fef5fcc10d52","repo":"Netflix/chaosmonkey","slug":"body-read-failed-at-s-1e44fe","errorCode":null,"errorMessage":"body read failed at %s","messagePattern":"body read failed at (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"spinnaker/terminator.go","lineNumber":158,"sourceCode":"// OtherID returns the alternate instance id of an instance, if it exists\n// If there is no alternate instance id, it returns an empty string\n// This is used by Titus, where we also report the uuid\nfunc (s Spinnaker) OtherID(ins chaosmonkey.Instance) (otherID string, err error) {\n\turl := s.instanceURL(ins.AccountName(), ins.RegionName(), ins.ID())\n\tresp, err := s.client.Get(url)\n\tif err != nil {\n\t\treturn \"\", errors.Wrap(err, fmt.Sprintf(\"get failed on %s\", url))\n\t}\n\n\tdefer func() {\n\t\tif cerr := resp.Body.Close(); cerr != nil && err == nil {\n\t\t\terr = errors.Wrap(cerr, fmt.Sprintf(\"failed to close response body from %s\", url))\n\t\t}\n\t}()\n\n\tbody, err := ioutil.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn \"\", errors.Wrap(err, fmt.Sprintf(\"body read failed at %s\", url))\n\t}\n\n\t// Example of response body:\n\t/*\n\t\t{\n\t\t\t...\n\t\t\t\"health\": [\n\t\t\t\t{\n\t\t\t\t\t\"type\": \"Titus\",\n\t\t\t\t\t\"healthClass\": \"platform\",\n\t\t\t\t\t\"state\": \"Up\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"instanceId\": \"55fe33ab-5b66-450a-85f7-f3129806b87f\",\n\t\t\t\t\t\"titusTaskId\": \"Titus-123456-worker-0-0\",\n\t\t\t\t\t...\n\t\t\t\t}\n\t\t\t],","sourceCodeStart":140,"sourceCodeEnd":176,"githubUrl":"https://github.com/Netflix/chaosmonkey/blob/eaa28fb761c0ebe8644d1333e5d164e9cc3071e9/spinnaker/terminator.go#L140-L176","documentation":"OtherID throws this when ioutil.ReadAll fails while reading the body of the Spinnaker instance endpoint response. The HTTP response arrived (status checked later), but the body stream could not be fully consumed — the connection broke mid-read or a read error occurred. The instance URL is included to identify the failing request; it aborts the lookup of the instance's alternate (Titus) ID.","triggerScenarios":"GET <spinnaker-api>/<account>/<region>/<instanceId> returned headers, but reading resp.Body hit a non-EOF error: mid-transfer connection reset, truncated chunked encoding, or a read timeout on a stalled body.","commonSituations":"Gate under heavy load producing stalled/truncated responses; LB idle timeouts killing slow responses; flaky network between chaosmonkey and Spinnaker; Titus instance lookups of large task metadata being interrupted.","solutions":["Retry the GET; transient read errors usually clear on a second attempt.","Check errors.Cause to distinguish unexpected EOF, connection reset, or timeout, and address the matching layer.","Increase client read timeouts and check LB/proxy response timeouts.","Verify Gate health and scale/latency at the time of failure.","Bound the read with io.LimitReader and consider partial-tolerant parsing if bodies are large."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// retry the whole GET if the body read fails; the request is idempotent\nvar body []byte\nfor i := 0; i < 3; i++ {\n\tresp, err := client.Get(url)\n\tif err != nil {\n\t\tcontinue\n\t}\n\tbody, err = ioutil.ReadAll(io.LimitReader(resp.Body, 1<<20))\n\tresp.Body.Close()\n\tif err == nil {\n\t\tbreak\n\t}\n}\nif body == nil {\n\treturn fmt.Errorf(\"body read failed at %s after retries\", url)\n}","typeGuard":null,"tryCatchPattern":"body, err := ioutil.ReadAll(resp.Body)\nif err != nil {\n\tif ne, ok := errors.Cause(err).(net.Error); ok && ne.Timeout() {\n\t\t// retry with longer read timeout\n\t}\n\treturn \"\", errors.Wrap(err, fmt.Sprintf(\"body read failed at %s\", url))\n}","preventionTips":["Use io.LimitReader to cap reads and reduce exposure to stalled bodies","Increase client read timeouts if bodies are large or Gate is slow","Check LB/proxy response timeouts vs Gate latency under load","Retry idempotent GETs on transient read errors"],"tags":["go","http","io","network","spinnaker"],"backgroundTag":"http-body-read-failed","analyzedSha":"eaa28fb761c0ebe8644d1333e5d164e9cc3071e9","analyzedAt":"2026-09-03T17:04:39.020Z","contentChangedAt":"2026-09-03T17:04:39.020Z","schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}