{"record":{"id":"ca0ed60ac42be663","repo":"XTLS/Xray-core","slug":"authentication-rejected","errorCode":null,"errorMessage":"authentication rejected","messagePattern":"authentication rejected","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"transport/internet/finalmask/xmc/client.go","lineNumber":201,"sourceCode":"\t// Enable encryption\n\tc.reader, err = newCryptoReader(c.reader, sharedSecret)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"new crypto reader: %w\", err)\n\t}\n\n\tc.writer, err = newCryptoWriter(c.writer, sharedSecret)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"new crypto writer: %w\", err)\n\t}\n\n\tpkt, err = readPacket(c.reader)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"read login finished: %w\", err)\n\t}\n\tif pkt.packetID == 0x00 {\n\t\tvar reason String\n\t\tif readErr := pkt.readFields(&reason); readErr != nil {\n\t\t\treturn fmt.Errorf(\"authentication rejected\")\n\t\t}\n\t\treturn fmt.Errorf(\"authentication rejected: %s\", reason)\n\t}\n\tif pkt.packetID != 0x02 {\n\t\treturn fmt.Errorf(\"bad login finished packet id: %d\", pkt.packetID)\n\t}\n\n\treceivedProfile, err := readLoginSuccess(pkt)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"read login finished fields: %w\", err)\n\t}\n\tif receivedProfile != selectedProfile {\n\t\treturn fmt.Errorf(\"login profile mismatch\")\n\t}\n\tloginAcknowledgedLength, err := writePacketWithLength(c.writer, 0x03)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"write login acknowledged: %w\", err)\n\t}","sourceCodeStart":183,"sourceCodeEnd":219,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/transport/internet/finalmask/xmc/client.go#L183-L219","documentation":"After encryption was established, the server sent packet ID 0x00 (Login Disconnect / authentication rejected), but the client additionally failed to decode the reason string from that packet's fields (readFields on a String failed — malformed varint length or truncated body). The error deliberately hides the parse detail; the real event is that the server rejected authentication.","triggerScenarios":"First Read/Write on the wrapped conn: server replies 0x00 with a malformed or empty reason payload (e.g. empty body after the packet ID, or non-UTF8/oversized length prefix), so pkt.readFields(&reason) errors and the client returns the bare 'authentication rejected'.","commonSituations":"Password mismatch where the server's disconnect reason is a Chat component the simple String reader cannot parse; a server version that formats the reason differently; or truncation by a middlebox.","solutions":["Treat it exactly like 'authentication rejected': verify the shared password between client and server","Check the server's xmc implementation/version to see what reason payload it sends on 0x00","Capture the packet if the reason matters — the client discards it in this branch","Ensure profiles (username/UUID) are valid and accepted by the server"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"_, err := conn.Read(buf)\nif err != nil && strings.Contains(err.Error(), \"authentication rejected\") {\n    return fmt.Errorf(\"xmc auth failed (password mismatch?): verify shared secret config\")\n}","preventionTips":["Keep the pre-shared password identical on both ends","Normalize config strings (trim whitespace) at load time","Surface auth failures to monitoring; they indicate config drift, not bugs"],"tags":["auth","handshake","password","protocol","go"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}