{"record":{"id":"9af1fa09f69ea0fa","repo":"XTLS/Xray-core","slug":"failed-to-write-response-9af1fa","errorCode":null,"errorMessage":"failed to write response","messagePattern":"failed to write response","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"proxy/trojan/server.go","lineNumber":349,"sourceCode":"\n\tlink, err := dispatcher.Dispatch(ctx, destination)\n\tif err != nil {\n\t\treturn errors.New(\"failed to dispatch request to \", destination).Base(err)\n\t}\n\n\trequestDone := func() error {\n\t\tdefer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly)\n\t\tif buf.Copy(clientReader, link.Writer, buf.UpdateActivity(timer)) != nil {\n\t\t\treturn errors.New(\"failed to transfer request\").Base(err)\n\t\t}\n\t\treturn nil\n\t}\n\n\tresponseDone := func() error {\n\t\tdefer timer.SetTimeout(sessionPolicy.Timeouts.UplinkOnly)\n\n\t\tif err := buf.Copy(link.Reader, clientWriter, buf.UpdateActivity(timer)); err != nil {\n\t\t\treturn errors.New(\"failed to write response\").Base(err)\n\t\t}\n\t\treturn nil\n\t}\n\n\trequestDonePost := task.OnSuccess(requestDone, task.Close(link.Writer))\n\tif err := task.Run(ctx, requestDonePost, responseDone); err != nil {\n\t\tcommon.Must(common.Interrupt(link.Reader))\n\t\tcommon.Must(common.Interrupt(link.Writer))\n\t\treturn errors.New(\"connection ends\").Base(err)\n\t}\n\n\treturn nil\n}\n\nfunc (s *Server) fallback(ctx context.Context, err error, sessionPolicy policy.Session, connection stat.Connection, iConn stat.Connection, napfb map[string]map[string]map[string]*Fallback, first *buf.Buffer, firstLen int64, reader buf.Reader) error {\n\tif err := connection.SetReadDeadline(time.Time{}); err != nil {\n\t\terrors.LogWarningInner(ctx, err, \"unable to set back read deadline\")\n\t}","sourceCodeStart":331,"sourceCodeEnd":367,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/proxy/trojan/server.go#L331-L367","documentation":"Copying the outbound's downlink bytes back to the trojan client failed (buf.Copy from link.Reader to clientWriter). The response-direction pipe aborted because the client connection write failed or the outbound link reader was interrupted.","triggerScenarios":"Client half-closed or reset while the remote still sent data, the inactivity timer fired during UplinkOnly phase, or the outbound reader was interrupted after the request pipe finished and closed the link.","commonSituations":"Browsers/apps closing the trojan connection on page cancel, mobile clients backgrounding, or large downloads interrupted by network change.","solutions":["If paired with [724]/[726] at connection end, treat as normal close sequencing","Check client-side firewall/NAT state for mid-stream resets on the trojan port","Verify the Timeouts.UplinkOnly policy window is not too aggressive for your traffic pattern"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := buf.Copy(link.Reader, clientWriter, buf.UpdateActivity(timer)); err != nil {\n    // downlink broke: the client cannot be written to anymore; end session\n    return errors.New(\"failed to write response\").Base(err)\n}","preventionTips":["Do not attempt write-after-failure on the client conn; the relay tears it down","Keep UplinkOnly timeout proportional to expected server response latency","Monitor for clusters of this error to detect client-side network churn vs server issues"],"tags":["trojan","relay","copy"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}