XTLS/Xray-core · warning
failed to flush payload
Error message
failed to flush payload
What it means
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.
Source
Thrown at proxy/trojan/client.go:124
Target: destination,
Account: account,
}
var bodyWriter buf.Writer
if destination.Network == net.Network_UDP {
bodyWriter = &PacketWriter{Writer: connWriter, Target: destination}
} else {
bodyWriter = connWriter
}
// write some request payload to buffer
if err = buf.CopyOnceTimeout(link.Reader, bodyWriter, time.Millisecond*100); err != nil && err != buf.ErrNotTimeoutReader && err != buf.ErrReadTimeout {
return errors.New("failed to write A request payload").Base(err).AtWarning()
}
// Flush; bufferWriter.WriteMultiBuffer now is bufferWriter.writer.WriteMultiBuffer
if err = bufferWriter.SetBuffered(false); err != nil {
return errors.New("failed to flush payload").Base(err).AtWarning()
}
// Send header if not sent yet
if _, err = connWriter.Write([]byte{}); err != nil {
return err.(*errors.Error).AtWarning()
}
if err = buf.Copy(link.Reader, bodyWriter, buf.UpdateActivity(timer)); err != nil {
return errors.New("failed to transfer request payload").Base(err).AtInfo()
}
return nil
}
getResponse := func() error {
defer timer.SetTimeout(sessionPolicy.Timeouts.UplinkOnly)
var reader buf.ReaderView on GitHub (pinned to 7d214f8b09)
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.
Defensive patterns
Strategy: try-catch
Try / catch
if err := client.Process(ctx, link, dialer); err != nil {
if strings.Contains(err.Error(), "failed to flush payload") {
// inspect base error for reset-vs-TLS cause; verify serverName/ALPN/password
}
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: Server RST right after handshake (auth rejected); aggressive connectionIdle policy cancelling the context before the flush; middlebox interference on early TLS application data.
Related errors
- Trojan settings: "servers" should have one and only one memb
- no target server found
- failed to get server spec
- target not specified
- failed to find an available destination
AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15).
Data as JSON: /api/errors/5d3521a5ac7020e4.
Report an issue: GitHub.