{"record":{"id":"8655d452e6639eaa","repo":"XTLS/Xray-core","slug":"write-handshake-packet-w","errorCode":null,"errorMessage":"write handshake packet: %w","messagePattern":"write handshake packet: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"transport/internet/finalmask/xmc/client.go","lineNumber":104,"sourceCode":"\t\tserverPort      UnsignedShort = UnsignedShort(25565)\n\t\tnextState       Varint        = Varint(2)\n\t)\n\n\thost, portString, err := net.SplitHostPort(c.c.RemoteAddr().String())\n\tif err == nil {\n\t\tport, err := strconv.Atoi(portString)\n\t\tif err == nil {\n\t\t\tserverPort = UnsignedShort(port)\n\t\t}\n\n\t\tif serverAddress == \"\" {\n\t\t\tserverAddress = String(host)\n\t\t}\n\t}\n\n\terr = writePacket(c.writer, 0x00, &protocolVersion, &serverAddress, &serverPort, &nextState)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"write handshake packet: %w\", err)\n\t}\n\n\t// Login Start\n\trandomProfile, err := rand.Int(rand.Reader, big.NewInt(int64(len(c.profiles))))\n\tif err != nil {\n\t\treturn fmt.Errorf(\"select profile: %w\", err)\n\t}\n\tselectedProfile := c.profiles[randomProfile.Int64()]\n\tusername := String(selectedProfile.Username)\n\n\terr = writePacket(c.writer, 0x00, &username, &selectedProfile.UUID)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"write login start: %w\", err)\n\t}\n\n\t// Encryption Request\n\tpkt, err := readPacket(c.reader)\n\tif err != nil {","sourceCodeStart":86,"sourceCodeEnd":122,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/transport/internet/finalmask/xmc/client.go#L86-L122","documentation":"Wraps a writePacket failure when sending the Minecraft handshake packet (packet ID 0x00 with protocol version 775, host, port 25565, next state 2). The %w chains the underlying write error on the client's writer, so the cause is almost always the TCP connection state.","triggerScenarios":"The socket breaking between TCP connect and the first write: server RST, idle-timeout disconnect, deadline expired, or a proxy in front dropping the connection. writePacket serializes Varint/String/UnsignedShort fields and fails on the first short write.","commonSituations":"Pointing the client at a host that immediately closes connections (wrong port, firewall REJECT with reset); handshake deadline too short for a slow link; NAT middlebox killing the flow.","solutions":["Verify the target hostname/port and that the server speaks the Minecraft protocol.","Unwrap the %w to distinguish i/o timeout from broken pipe/ECONNRESET.","Retry the connection; transient resets during dial are common, and the transport re-handshakes on a fresh conn."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := cc.Handshake(); err != nil {\n\tif isTransientWriteErr(err) { // ECONNRESET, broken pipe, i/o timeout\n\t\treturn backoff.RetryDial(ctx, target) // fresh conn, full re-handshake\n\t}\n\treturn err\n}","preventionTips":["Retry with a fresh connection and full handshake; the Minecraft handshake is not resumable.","Verify host/port reachability (TCP dial + a plain Minecraft ping) before blaming the transport."],"tags":["network","xmc","finalmask","handshake","write"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}