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 nilView on GitHub (pinned to 7d214f8b09)
Solutions
- Upgrade both endpoints to matching library versions
- Capture traffic and confirm payload packets begin with the Varint length of "xmc:data"
- Eliminate stream-altering middleboxes (compression proxies, TLS-terminating LBs) on the path
- 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
- Pin library versions across endpoints
- Avoid paths that rewrite stream bytes (compressing proxies, MITM TLS)
- Log the channel error separately from I/O errors to identify protocol drift
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
- read minecraft keep-alive: %w
- read minecraft custom payload data: %w
- empty domain name
- authentication rejected
- bad login finished packet id: %d
AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15).
Data as JSON: /api/errors/602b0c1578cbb577.
Report an issue: GitHub.