XTLS/Xray-core · error

read minecraft custom payload channel: %w

Error message

read minecraft custom payload channel: %w

What it means

parseCustomPayload failed to read the channel-identifier String (Varint length + UTF-8 bytes) from a received custom-payload packet's data section. The packet body is already in memory, so this means the body is too short or the length prefix is malformed — internal framing corruption between the peers.

Source

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

func (s *packetStream) localCustomPayloadID() int {
	if s.isClient {
		return configurationServerboundCustomPayload
	}
	return configurationClientboundCustomPayload
}

func (s *packetStream) remoteCustomPayloadID() int {
	if s.isClient {
		return configurationClientboundCustomPayload
	}
	return configurationServerboundCustomPayload
}

func parseCustomPayload(packet *mcPacket) ([]byte, bool, error) {
	r := bytes.NewReader(packet.data)
	var channel String
	if err := channel.readFrom(r); err != nil {
		return nil, false, fmt.Errorf("read minecraft custom payload channel: %w", err)
	}
	if string(channel) != packetChannel {
		return nil, false, nil
	}
	payload := make([]byte, r.Len())
	if _, err := io.ReadFull(r, payload); err != nil {
		return nil, false, fmt.Errorf("read minecraft custom payload data: %w", err)
	}
	return payload, true, nil
}

func (s *packetStream) writeKeepAlive(id Long) error {
	s.writeMu.Lock()
	defer s.writeMu.Unlock()
	if err := writePacket(s.writer, configurationKeepAlive, &id); err != nil {
		return fmt.Errorf("write minecraft keep-alive: %w", err)
	}
	return nil

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Upgrade both endpoints to matching library versions
  2. Capture traffic and confirm payload packets begin with the Varint length of "xmc:data"
  3. Eliminate stream-altering middleboxes (compression proxies, TLS-terminating LBs) on the path
  4. Treat the connection as unrecoverable and reconnect
Defensive patterns

Strategy: try-catch

Try / catch

n, err := stream.Read(buf)
if err != nil && strings.Contains(err.Error(), "custom payload channel") {
    log.Printf("peer speaks a different xmc variant: %v", err)
    conn.Close()
}

Prevention

When it happens

Trigger: Remote sends a 0x01/0x02 custom-payload packet whose data does not start with a valid Minecraft String; typically caused by packet-ID mismatch between client and server builds or stream corruption.

Common situations: Client and server run different xmc versions with changed packet layouts; a middlebox mangles the stream; interoperating with a plugin that reuses the same packet IDs with a different body format.

Related errors


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