{"record":{"id":"5d3521a5ac7020e4","repo":"XTLS/Xray-core","slug":"failed-to-flush-payload","errorCode":null,"errorMessage":"failed to flush payload","messagePattern":"failed to flush payload","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"proxy/trojan/client.go","lineNumber":124,"sourceCode":"\t\t\tTarget:  destination,\n\t\t\tAccount: account,\n\t\t}\n\n\t\tvar bodyWriter buf.Writer\n\t\tif destination.Network == net.Network_UDP {\n\t\t\tbodyWriter = &PacketWriter{Writer: connWriter, Target: destination}\n\t\t} else {\n\t\t\tbodyWriter = connWriter\n\t\t}\n\n\t\t// write some request payload to buffer\n\t\tif err = buf.CopyOnceTimeout(link.Reader, bodyWriter, time.Millisecond*100); err != nil && err != buf.ErrNotTimeoutReader && err != buf.ErrReadTimeout {\n\t\t\treturn errors.New(\"failed to write A request payload\").Base(err).AtWarning()\n\t\t}\n\n\t\t// Flush; bufferWriter.WriteMultiBuffer now is bufferWriter.writer.WriteMultiBuffer\n\t\tif err = bufferWriter.SetBuffered(false); err != nil {\n\t\t\treturn errors.New(\"failed to flush payload\").Base(err).AtWarning()\n\t\t}\n\n\t\t// Send header if not sent yet\n\t\tif _, err = connWriter.Write([]byte{}); err != nil {\n\t\t\treturn err.(*errors.Error).AtWarning()\n\t\t}\n\n\t\tif err = buf.Copy(link.Reader, bodyWriter, buf.UpdateActivity(timer)); err != nil {\n\t\t\treturn errors.New(\"failed to transfer request payload\").Base(err).AtInfo()\n\t\t}\n\n\t\treturn nil\n\t}\n\n\tgetResponse := func() error {\n\t\tdefer timer.SetTimeout(sessionPolicy.Timeouts.UplinkOnly)\n\n\t\tvar reader buf.Reader","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/proxy/trojan/client.go#L106-L142","documentation":"Thrown by the trojan client when unbuffering the connection writer (bufferWriter.SetBuffered(false)) fails after the prime payload copy. Flushing pushes the trojan header plus the first payload bytes to the wire; any writer/TLS error at this point surfaces as this warning.","triggerScenarios":"The underlying buffered writer's Flush returns an error: trojan connection already reset by peer, TLS layer failed to write (cert/ALPN problem on very early data), or the connWriter was closed by the inactivity timer firing during the 100ms prime window.","commonSituations":"Server RST right after handshake (auth rejected); aggressive connectionIdle policy cancelling the context before the flush; middlebox interference on early TLS application data.","solutions":["Read the Base error to distinguish connection-reset from TLS failures.","Verify password and TLS settings (serverName, ALPN h2/http/1.1) match the trojan server.","Raise policy timeouts (handshake/connectionIdle) if very slow links cause premature cancels.","Compare client and server xray-core versions — trojan header/timing behavior changed across releases."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := client.Process(ctx, link, dialer); err != nil {\n\tif strings.Contains(err.Error(), \"failed to flush payload\") {\n\t\t// inspect base error for reset-vs-TLS cause; verify serverName/ALPN/password\n\t}\n}","preventionTips":["Match TLS serverName/ALPN between client and server.","Keep handshake/idle policy timeouts generous on slow links.","Align client and server core versions for trojan early-data behavior."],"tags":["trojan","outbound","flush","buffered-writer","tls"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}