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], nil

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Check the wrapped error for the real cause; connection-closed means stop writing and tear down.
  2. Keep byte-array fields under the protocol's 1024-byte read cap so peers can parse them.
  3. Buffer the full frame (encodePacket already does) and write once to minimize partial-write windows.
  4. 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

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.