{"record":{"id":"27be06f797713995","repo":"cloudflare/cloudflared","slug":"incoming-request-ended-abruptly","errorCode":null,"errorMessage":"Incoming request ended abruptly","messagePattern":"Incoming request ended abruptly","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"proxy/proxy.go","lineNumber":224,"sourceCode":"\t\t\tif err == nil {\n\t\t\t\troundTripReq.ContentLength = int64(cLength)\n\t\t\t}\n\t\t}\n\t\t// Request origin to keep connection alive to improve performance\n\t\troundTripReq.Header.Set(\"Connection\", \"keep-alive\")\n\t}\n\n\t// Set the User-Agent as an empty string if not provided to avoid inserting golang default UA\n\tif roundTripReq.Header.Get(\"User-Agent\") == \"\" {\n\t\troundTripReq.Header.Set(\"User-Agent\", \"\")\n\t}\n\n\t_, ttfbSpan := tr.Tracer().Start(tr.Context(), \"ttfb_origin\")\n\tresp, err := httpService.RoundTrip(roundTripReq)\n\tif err != nil {\n\t\ttracing.EndWithErrorStatus(ttfbSpan, err)\n\t\tif err := roundTripReq.Context().Err(); err != nil {\n\t\t\treturn errors.Wrap(err, \"Incoming request ended abruptly\")\n\t\t}\n\t\treturn errors.Wrap(err, \"Unable to reach the origin service. The service may be down or it may not be responding to traffic from cloudflared\")\n\t}\n\n\ttracing.EndWithStatusCode(ttfbSpan, resp.StatusCode)\n\tdefer func() { _ = resp.Body.Close() }()\n\n\theaders := make(http.Header, len(resp.Header))\n\t// copy headers\n\tfor k, v := range resp.Header {\n\t\theaders[k] = v\n\t}\n\n\t// Add spans to response header (if available)\n\ttr.AddSpans(headers)\n\n\terr = w.WriteRespHeaders(resp.StatusCode, headers)\n\tif err != nil {","sourceCodeStart":206,"sourceCodeEnd":242,"githubUrl":"https://github.com/cloudflare/cloudflared/blob/2253eeeb25a44a713a4b60b8ba1e1b3f377d1a0f/proxy/proxy.go#L206-L242","documentation":"In proxyHTTPRequest, the origin round trip (httpService.RoundTrip) failed AND the request context carried an error (canceled or deadline exceeded), meaning the CLIENT side of the request ended before the origin responded. The error is wrapped with this message instead of the generic origin-unreachable message.","triggerScenarios":"httpService.RoundTrip returns an error and roundTripReq.Context().Err() is non-nil — the client disconnected, the request timed out (context deadline), or cloudflared is shutting down and the context was canceled.","commonSituations":"Browsers/users canceling slow requests, origin timeouts shorter than origin processing time, aggressive proxy timeouts, or cloudflared shutdown mid-request.","solutions":["Check the wrapped context error: DeadlineExceeded means a timeout was hit; Canceled means the client went away.","Tune timeout settings (originRequest connectTimeout / the edge request timeout) if origins are legitimately slow.","Investigate why origins are slow enough to trigger client abandonment (slow queries, blocking work).","If this happens during shutdowns, it is expected — treat it as a normal cancellation, not an origin failure."],"exampleFix":"// before (config.yml)\noriginRequest:\n  connectTimeout: 5s   # too short for slow origin\n// after\noriginRequest:\n  connectTimeout: 30s","handlingStrategy":"try-catch","validationCode":"// Distinguish cancellation from origin failure before logging/alerting\nif rctx := roundTripReq.Context(); rctx.Err() != nil {\n    log.Debug().Err(rctx.Err()).Str(\"path\", r.URL.Path).Msg(\"client abandoned request\")\n    return\n}","typeGuard":null,"tryCatchPattern":"resp, err := httpService.RoundTrip(roundTripReq)\nif err != nil {\n    if ctxErr := roundTripReq.Context().Err(); ctxErr != nil {\n        log.Debug().Err(ctxErr).Msg(\"request canceled by client; not retrying\")\n        return\n    }\n    // otherwise: genuine origin failure — safe to retry\n}","preventionTips":["Set originRequest timeouts generously enough for your origin's worst-case latency.","Distinguish context.Canceled/DeadlineExceeded from real origin errors before alerting.","Monitor client-abandonment rates as a signal of slow origins.","Avoid retrying requests whose context is already canceled."],"tags":["timeout","context-cancelled","origin","proxy"],"backgroundTag":"request-timeout","analyzedSha":"2253eeeb25a44a713a4b60b8ba1e1b3f377d1a0f","analyzedAt":"2026-09-06T04:14:33.757Z","contentChangedAt":"2026-09-06T04:14:33.757Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}