XTLS/Xray-core · error
read encryption request fields: %w
Error message
read encryption request fields: %w
What it means
Wraps a readFields failure while decoding the Encryption Request body (serverId String, publicKey Bytes, verifyToken Bytes). The %w chains the field-decoding error, which occurs when the packet body is truncated or contains malformed varint lengths/UTF-8 for those field types.
Source
Thrown at transport/internet/finalmask/xmc/client.go:138
// Encryption Request
pkt, err := readPacket(c.reader)
if err != nil {
return fmt.Errorf("read encryption request: %w", err)
}
if pkt.packetID != 0x01 {
return fmt.Errorf("bad encrypt request packet id")
}
var (
serverId String
publicKey Bytes
verifyToken Bytes
)
err = pkt.readFields(&serverId, &publicKey, &verifyToken)
if err != nil {
return fmt.Errorf("read encryption request fields: %w", err)
}
if !bytes.Equal(publicKey, c.rsaPublicKey) {
return fmt.Errorf("server public key mismatch")
}
k, err := x509.ParsePKIXPublicKey(publicKey)
if err != nil {
return fmt.Errorf("parse server public key: %w", err)
}
rsaPublicKey, ok := k.(*rsa.PublicKey)
if !ok {
return fmt.Errorf("parse server public key: not rsa")
}
sharedSecret := make([]byte, 16)
if _, err = rand.Read(sharedSecret); err != nil {View on GitHub (pinned to 7d214f8b09)
Solutions
- Capture the actual bytes (hexdump the first packets) to see what the peer really sent.
- Bypass intermediate proxies when dialing the Minecraft port.
- Confirm the server runs an unmodified login protocol compatible with version 775.
Defensive patterns
Strategy: try-catch
Try / catch
if err := cc.Handshake(); err != nil {
var ferr *fieldDecodeError // if exposed; otherwise match message
if errors.As(err, &ferr) || strings.Contains(err.Error(), "read encryption request fields") {
return fmt.Errorf("peer is not speaking the expected login protocol: %w", err)
}
return err
} Prevention
- Hexdump the first packets when this fires; malformed bodies usually mean the wrong service answered.
- Avoid routing the Minecraft port through MITM/HTTP proxies.
When it happens
Trigger: A non-Minecraft or proxy server returning bytes that happen to parse as a packet but whose body does not match the String/Bytes/Bytes layout; a man-in-the-middle mangling the stream; a server using a modified protocol that reorders Encryption Request fields.
Common situations: Connecting through a MITM HTTP proxy that answers with its own payload; protocol forks (Paper/Forge) altering the packet body; truncation from middleboxes enforcing small first-packet sizes.
Related errors
- bad encrypt request packet id
- No available name server could be created from
- set deadline: %w
- write handshake packet: %w
- write login start: %w
AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15).
Data as JSON: /api/errors/42876cd9cb345957.
Report an issue: GitHub.