{"record":{"id":"e83d0024ac4d4a82","repo":"temporalio/temporal","slug":"failed-to-read-request-body-w","errorCode":null,"errorMessage":"failed to read request body: %w","messagePattern":"failed to read request body: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/persistence/visibility/store/elasticsearch/client/aws.go","lineNumber":38,"sourceCode":"type awsSigningTransport struct {\n\tcreds   aws.CredentialsProvider\n\tsigner  *v4signer.Signer\n\tregion  string\n\tservice string\n\twrapped http.RoundTripper\n}\n\nfunc (t *awsSigningTransport) RoundTrip(req *http.Request) (*http.Response, error) {\n\tcreds, err := t.creds.Retrieve(req.Context())\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to retrieve AWS credentials: %w\", err)\n\t}\n\n\tvar bodyBytes []byte\n\tif req.Body != nil {\n\t\tbodyBytes, err = io.ReadAll(req.Body)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to read request body: %w\", err)\n\t\t}\n\t\treq.Body = io.NopCloser(bytes.NewReader(bodyBytes))\n\t}\n\n\thash := fmt.Sprintf(\"%x\", sha256.Sum256(bodyBytes))\n\terr = t.signer.SignHTTP(req.Context(), creds, req, hash, t.service, t.region, time.Now())\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to sign request: %w\", err)\n\t}\n\n\tif bodyBytes != nil {\n\t\t// set the request body just in case the signer consumes the body\n\t\treq.Body = io.NopCloser(bytes.NewReader(bodyBytes))\n\t}\n\n\treturn t.wrapped.RoundTrip(req)\n}\n","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/temporalio/temporal/blob/bde624efd13fbd3843654058db6d9c716166318b/common/persistence/visibility/store/elasticsearch/client/aws.go#L20-L56","documentation":"awsSigningTransport.RoundTrip must read the full request body into memory to compute the SHA-256 payload hash required by AWS SigV4 signing. If io.ReadAll on req.Body fails, the request is aborted with this wrapped error and never sent to Elasticsearch.","triggerScenarios":"Any visibility request whose req.Body stream errors during read: connection reset to an intermediate proxy mid-write, body already consumed/closed by an earlier middleware, or an I/O fault in a custom wrapped transport below the signer.","commonSituations":"Pipelined/proxied HTTP where an upstream connection breaks while streaming a large bulk-search query; a middleware chain that read and did not rewind the body before the signing transport; transient network faults in busy visibility clusters with large requests.","solutions":["Retry the request — this is typically a transient network/stream error, not a config problem","Check for middleware that reads req.Body without resetting it via io.NopCloser(bytes.NewReader(...)) before the AWS signing transport","Inspect the wrapped error for proxy/TLS connection resets and fix the underlying network path","Reduce request payload size if timeouts on large bodies are implicated"],"exampleFix":"// before: middleware consumed body and did not rewind\nbody, _ := io.ReadAll(req.Body)\nreq.Body = nil\n// after: always restore the body\nbody, _ := io.ReadAll(req.Body)\nreq.Body = io.NopCloser(bytes.NewReader(body))","handlingStrategy":"retry","validationCode":"// ensure any middleware has not consumed the body: it must be non-nil and unread\nif req.Body != nil {\n    if req.GetBody == nil && req.ContentLength > 0 {\n        // body may not be rewindable; avoid chaining readers before the signing transport\n    }\n}","typeGuard":null,"tryCatchPattern":"resp, err := client.Do(req)\nif err != nil && strings.Contains(err.Error(), \"failed to read request body\") {\n    // transient I/O — rebuild request and retry\n    ...\n}","preventionTips":["Never read req.Body in middleware without restoring it via io.NopCloser(bytes.NewReader(b))","Place the AWS signing transport outermost or ensure earlier roundtrippers don't consume streams","Keep visibility request payloads within sane size limits to reduce mid-stream faults","Monitor proxy/TLS connection resets in the visibility network path"],"tags":["go","aws","elasticsearch","http","request-body","sigv4"],"backgroundTag":"request-body-read-failed","analyzedSha":"bde624efd13fbd3843654058db6d9c716166318b","analyzedAt":"2026-09-01T07:18:39.080Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}