XTLS/Xray-core · error
write remaining bytes: %w
Error message
write remaining bytes: %w
What it means
RestBytes.writeTo writes the raw trailing bytes to the io.Writer and wraps any Write failure. As with the other write wrappers, the encoding cannot fail; this is an underlying connection/buffer error while flushing the tail of a packet.
Source
Thrown at transport/internet/finalmask/xmc/protocol.go:348
*v = append([]byte(*v), buf...)
return nil
}
type RestBytes []byte
func (v *RestBytes) readFrom(r io.Reader) error {
buf, err := io.ReadAll(r)
if err != nil {
return fmt.Errorf("read remaining bytes: %w", err)
}
*v = append((*v)[:0], buf...)
return nil
}
func (v *RestBytes) writeTo(w io.Writer) error {
if _, err := w.Write(*v); err != nil {
return fmt.Errorf("write remaining bytes: %w", err)
}
return nil
}
func (v *Bytes) writeTo(w io.Writer) error {
length := Varint(len(*v))
err := length.writeTo(w)
if err != nil {
return fmt.Errorf("write bytes length: %w", err)
}
_, err = w.Write(*v)
if err != nil {
return fmt.Errorf("write bytes: %w", err)
}
return nil
}View on GitHub (pinned to 7d214f8b09)
Solutions
- Unwrap and classify: ErrConnClosed/broken pipe => peer gone, skip further writes; timeout => deadline too tight or network stalled.
- Serialize all writes through one writer goroutine/channel so close-vs-write races cannot happen.
- Once any write fails, abandon the connection instead of attempting more packet writes.
- Tune write deadlines to the expected RTT and payload size.
Defensive patterns
Strategy: try-catch
Try / catch
if err := rest.writeTo(w); err != nil {
if errors.Is(err, net.ErrClosed) || isBrokenPipe(err) {
stopWriterLoop()
return nil // peer gone; nothing more to flush
}
return err
} Prevention
- Funnel all sends through one writer goroutine to avoid close/write races.
- Skip trailing writes once teardown has begun.
- Abandon the connection after its first write error.
When it happens
Trigger: Sending a packet with a RestBytes payload after the peer disconnected; write deadline exceeded; underlying conn already closed by another goroutine or by error handling elsewhere.
Common situations: Writing a final close/flush packet after the remote already went away; races between a watchdog closing the conn and the encoder still writing; outbound proxy failure beneath the transport.
Related errors
AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15).
Data as JSON: /api/errors/3af8d25356e10ca4.
Report an issue: GitHub.