XTLS/Xray-core · error
write bytes length: %w
Error message
write bytes length: %w
What it means
Bytes.writeTo first emits the payload length as a Varint; this error wraps a failure of that Varint write. In practice the writer is an in-memory bytes.Buffer during encodePacket, so seeing this escape to a caller means the failure happened on the framed write path (writePacketWithLength's writeFull) or a custom writer, not from bad data.
Source
Thrown at transport/internet/finalmask/xmc/protocol.go:357
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
}
func readByte(r io.Reader) (byte, error) {
var buf [1]byte
_, err := io.ReadFull(r, buf[:])
if err != nil {
return 0, fmt.Errorf("read byte: %w", err)
}
return buf[0], nilView on GitHub (pinned to 7d214f8b09)
Solutions
- Check the wrapped error for the real cause; connection-closed means stop writing and tear down.
- Keep byte-array fields under the protocol's 1024-byte read cap so peers can parse them.
- Buffer the full frame (encodePacket already does) and write once to minimize partial-write windows.
- Increase write deadline if the error is a timeout on large frames.
Defensive patterns
Strategy: try-catch
Try / catch
if err := f.writeTo(w); err != nil {
var nerr net.Error
if errors.As(err, &nerr) && nerr.Timeout() {
w.SetWriteDeadline(time.Now().Add(2 * deadline))
return err // caller may retry the whole frame on a fresh conn
}
return err
} Prevention
- Size write deadlines to the largest frame you send.
- Encode into a buffer first (encodePacket) and write once.
- Reject/avoid payloads that would push fields past the peer's 1024-byte read cap.
When it happens
Trigger: Encoding a packet with a Bytes field while the connection is closed/stalled; a custom io.Writer passed into the protocol layer returning an error on the first bytes of a field.
Common situations: Peer disconnected just before a byte-array field was flushed; write deadline smaller than the time to serialize a large field; test doubles that inject write errors.
Related errors
AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15).
Data as JSON: /api/errors/07bf6aa3c782152d.
Report an issue: GitHub.