XTLS/Xray-core · error

read minecraft packet stream: %w

Error message

read minecraft packet stream: %w

What it means

packetStream.Read failed while framing the next Minecraft configuration packet from the underlying connection (readPacket). This wraps I/O errors (connection reset, EOF, deadline exceeded) and framing errors from the peer's byte stream, e.g. a Varint length prefix that is too large or a truncated packet body.

Source

Thrown at transport/internet/finalmask/xmc/packet_stream.go:69

func (s *packetStream) Read(p []byte) (int, error) {
	if len(p) == 0 {
		return 0, nil
	}

	s.readMu.Lock()
	defer s.readMu.Unlock()

	if len(s.pending) > 0 {
		n := copy(p, s.pending)
		s.pending = s.pending[n:]
		return n, nil
	}

	for {
		packet, err := readPacket(s.reader)
		if err != nil {
			return 0, fmt.Errorf("read minecraft packet stream: %w", err)
		}

		if packet.packetID == s.remoteCustomPayloadID() {
			payload, ok, err := parseCustomPayload(packet)
			if err != nil {
				return 0, err
			}
			if !ok || len(payload) == 0 {
				continue
			}

			n := copy(p, payload)
			if n < len(payload) {
				s.pending = append(s.pending[:0], payload[n:]...)
			}
			return n, nil
		}

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Check errors.Is(err, io.EOF) / errors.Is(err, net.ErrClosed) to distinguish clean close from corruption
  2. Verify both endpoints run compatible xmc builds so packet IDs 0x01/0x02/0x04 and framing match
  3. Ensure the server-side keep-alive loop is active so NAT mappings do not expire
  4. Treat as fatal for the connection: tear down the wrapped net.Conn and reconnect at the application layer

Example fix

n, err := stream.Read(buf)
if err != nil {
    if errors.Is(err, io.EOF) || errors.Is(err, syscall.ECONNRESET) {
        return handleDisconnect()
    }
    return fmt.Errorf("xmc stream failed: %w", err)
}
Defensive patterns

Strategy: try-catch

Try / catch

n, err := stream.Read(buf)
if err != nil {
    if errors.Is(err, io.EOF) || errors.Is(err, net.ErrClosed) {
        // clean teardown path
        return nil
    }
    return fmt.Errorf("xmc read: %w", err)
}

Prevention

When it happens

Trigger: Reading from an xmc packetStream after the peer closes or resets the TCP connection; peer sends malformed packet framing (oversized Varint, short body); connection deadline fires during a read.

Common situations: Real Minecraft server or middlebox rejects the camouflage stream and closes; NAT idle timeout kills the connection between keep-alives; protocol version drift makes the peer's packets unparseable; proxy chain (the actual tunnel payload) misbehaves.

Related errors


AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15). Data as JSON: /api/errors/03287c7999eb4e47. Report an issue: GitHub.