XTLS/Xray-core · warning
failed to write A request payload
Error message
failed to write A request payload
What it means
Raised when the first-chunk probe copy (buf.CopyOnceTimeout with a 100ms budget) of the client's TCP payload fails with an error other than the two expected timeout conditions. It is marked AtWarning because a slow client that sends nothing within 100ms is normal; only a genuine write error (e.g. broken socket while relaying the first payload bytes) triggers it. The task then aborts the request direction.
Source
Thrown at proxy/shadowsocks/client.go:127
newCancel()
}
}, sessionPolicy.Timeouts.ConnectionIdle)
if newCtx != nil {
ctx = newCtx
}
if request.Command == protocol.RequestCommandTCP {
requestDone := func() error {
defer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly)
bufferedWriter := buf.NewBufferedWriter(buf.NewWriter(conn))
bodyWriter, err := WriteTCPRequest(request, bufferedWriter)
if err != nil {
return errors.New("failed to write request").Base(err)
}
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()
}
if err := bufferedWriter.SetBuffered(false); err != nil {
return err
}
return buf.Copy(link.Reader, bodyWriter, buf.UpdateActivity(timer))
}
responseDone := func() error {
defer timer.SetTimeout(sessionPolicy.Timeouts.UplinkOnly)
responseReader, err := ReadTCPResponse(user, conn)
if err != nil {
return err
}
return buf.Copy(responseReader, link.Writer, buf.UpdateActivity(timer))View on GitHub (pinned to 7d214f8b09)
Solutions
- Verify password and cipher method match exactly between client outbound and server inbound — a mismatch makes the server drop the connection on first data.
- Check server logs for AEAD authentication failures at the same timestamp.
- Confirm no DPI/middlebox is resetting the stream (tcpdump on client host).
- If the client app legitimately aborts instantly, this warning can be ignored; otherwise retest with curl through the proxy.
Example fix
// before
"outbounds": [{ "protocol": "shadowsocks", "settings": { "servers": [
{ "address": "srv", "port": 8388, "method": "aes-128-gcm", "password": "client-side-pass" } ] } }]
// after: align credentials with the server inbound
{ "address": "srv", "port": 8388, "method": "aes-128-gcm", "password": "server-side-pass" } Defensive patterns
Strategy: try-catch
Try / catch
// warning-level: inspect base cause, usually safe to surface and close the link
if err := requestDone(); err != nil && !errors.Is(err, buf.ErrReadTimeout) {
log.Warn("ss first payload write failed: ", err)
} Prevention
- Keep cipher/password identical on both ends to avoid server-side AEAD reject-close.
- Do not treat this warning alone as server failure; correlate with server logs.
- Test with a deterministic client (curl) to separate app-abort noise from real resets.
When it happens
Trigger: Dispatching a TCP request through the Shadowsocks client where link.Reader yields a first payload chunk but writing it through the AEAD body writer fails — connection reset by the remote server between the header write and the first payload write, or an encoder error inside the cipher stream.
Common situations: Server closes the socket immediately after a wrong password/cipher mismatch (AEAD decrypt failure on server causes instant close); middlebox RST on first data bytes; client application (browser) aborting the request within the first 100ms producing unexpected reader state.
Related errors
- failed to write request
- connection ends
- failed to transport all UDP request
- failed to transport all UDP response
- write encryption response: %w
AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15).
Data as JSON: /api/errors/13cfc318bf83b521.
Report an issue: GitHub.