XTLS/Xray-core · warning
failed to write A request payload
Error message
failed to write A request payload
What it means
Thrown during the trojan client's header-priming step: it attempts to copy one batch of request payload (with a 100ms timeout) into the trojan connection right after writing the header, so that the trojan server sees request bytes together with the header (mitigating replay fingerprinting). Only genuine copy errors (not the expected timeout/no-timeout-reader sentinel errors) produce this warning.
Source
Thrown at proxy/trojan/client.go:119
bufferWriter := buf.NewBufferedWriter(buf.NewWriter(conn))
connWriter := &ConnWriter{
Writer: bufferWriter,
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
}View on GitHub (pinned to 7d214f8b09)
Solutions
- Check the Base error and the trojan server logs at the same timestamp — an immediate server-side close usually means password mismatch.
- Verify the trojan password matches exactly on both ends.
- If the error is a TLS/write failure, inspect streamSettings (ALPN, serverName) on the client.
- Retry once: transient resets during prime-write are occasionally caused by server restarts.
Defensive patterns
Strategy: try-catch
Try / catch
if err := client.Process(ctx, link, dialer); err != nil {
if strings.Contains(err.Error(), "failed to write A request payload") {
// check base error: immediate server RST usually means password mismatch
}
} Prevention
- Confirm passwords match on both ends before debugging deeper.
- Watch trojan server logs for early-close events at the same timestamps.
- Treat transient resets at this stage as retryable once.
When it happens
Trigger: buf.CopyOnceTimeout(link.Reader, bodyWriter, 100ms) returns an error that is neither buf.ErrNotTimeoutReader nor buf.ErrReadTimeout — e.g. the downstream connection writer fails (connection reset by the trojan server mid-handshake) or the inbound reader errors out.
Common situations: Trojan server closing the connection immediately after connect (wrong password → server drops after reading hash); upstream connection reset during early payload; outbound connWriter TLS error surfacing here.
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/952ea9336ac5e63c.
Report an issue: GitHub.