{"record":{"id":"b24df33f99073548","repo":"gravitational/teleport","slug":"resperr-error","errorCode":null,"errorMessage":"respErr.Error()","messagePattern":"respErr\\.Error\\(\\)","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"lib/kube/proxy/forwarder.go","lineNumber":767,"sourceCode":"\t\t\treturn nil, trace.Wrap(err)\n\t\t}\n\t\terr = f.acquireConnectionLockWithIdentity(req.Context(), authContext)\n\t\tif err != nil {\n\t\t\treturn nil, trace.Wrap(err)\n\t\t}\n\t\treturn handler(authContext, w, req, p)\n\t}, f.formatStatusResponseError)\n}\n\nfunc (f *Forwarder) formatForwardResponseError(rw http.ResponseWriter, r *http.Request, respErr error) {\n\tf.formatStatusResponseError(rw, respErr)\n}\n\n// writeResponseErrorToBody writes the error response to the body without any formatting.\n// It is used for the /version endpoint since Kubernetes doesn't expect a JSON response\n// for that endpoint.\nfunc (f *Forwarder) writeResponseErrorToBody(rw http.ResponseWriter, respErr error) {\n\thttp.Error(rw, respErr.Error(), http.StatusInternalServerError)\n}\n\n// formatForwardResponseError handles errors returned from requests to the Kubernetes API.\n// Any errors produced as a result of a GOAWAY request are forwarded to users as [http.StatusTooManyRequests]\n// with a Retry-After header set to inform clients that they should retry the request. All\n// other errors are formatted as a [metav1.Status] and written to the [http.ResponseWriter].\nfunc (f *Forwarder) formatStatusResponseError(rw http.ResponseWriter, respErr error) {\n\t// This detects failed requests that were terminated by the server due to GOAWAY. There\n\t// is no direct way to detect these errors. No exported constants or error types exist from the\n\t// standard library, so we have to match on the error message. The two error strings come from:\n\t//   - golang.org/x/net/http2 when its internal retry path cannot replay the body:\n\t//     https://github.com/golang/net/blob/5ac9daca088ab4f378d7df849f6c7d28bea86071/http2/transport.go#L694\n\t//   - net/http (errCannotRewind) when, after the http2 conn pool is drained, the http1 retry\n\t//     path tries to rewind the body and fails because Request.GetBody is unset:\n\t//     https://github.com/golang/go/blob/go1.26.2/src/net/http/transport.go#L759\n\t// When a failed request is found, we return a response that indicates  to clients that they\n\t// should retry the request themselves.\n\terrString := respErr.Error()","sourceCodeStart":749,"sourceCodeEnd":785,"githubUrl":"https://github.com/gravitational/teleport/blob/1283425b60ec5f60d509ba4c791183d452923ff7/lib/kube/proxy/forwarder.go#L749-L785","documentation":"In the kube proxy forwarder's error formatting, this writes the status text for the HTTP status code derived from the error (via trace.ErrorToCode) as the response body when a proxied Kubernetes request fails; the literal text is the standard reason phrase (e.g. 'Unauthorized') for the mapped code.","triggerScenarios":"Thrown at lib/kube/proxy/forwarder.go:767 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Check the Kubernetes client's output and proxy logs for the underlying error","Address the root cause per the status code: authenticate (401), fix RBAC permissions (403), or verify the resource exists (404)","Retry transient failures (5xx)"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"1283425b60ec5f60d509ba4c791183d452923ff7","analyzedAt":"2026-09-02T04:06:41.601Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}