{"record":{"id":"607bdeeb9204babd","repo":"XTLS/Xray-core","slug":"empty-rsa-public-key","errorCode":null,"errorMessage":"empty rsa public key","messagePattern":"empty rsa public key","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"transport/internet/finalmask/xmc/client.go","lineNumber":46,"sourceCode":"\tprofiles        []loginProfile\n\tpassword        string\n\trsaPublicKey    []byte\n\thostname        string\n\tpaddingSchedule []paddingTurn\n\tpacket          *packetStream\n\tdeadlines       *connectionDeadlines\n}\n\ntype clientState int\n\nvar (\n\tclientStateHandshake clientState = 1\n\tclientStateProxy     clientState = 2\n)\n\nfunc newClientConn(c net.Conn, profiles []loginProfile, password string, rsaPublicKey []byte, hostname string) (*clientConn, error) {\n\tif len(rsaPublicKey) == 0 {\n\t\treturn nil, fmt.Errorf(\"empty rsa public key\")\n\t}\n\tif len(profiles) == 0 {\n\t\treturn nil, fmt.Errorf(\"empty profiles\")\n\t}\n\tpaddingSchedule, err := newClientPaddingSchedule2612()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"select padding profile: %w\", err)\n\t}\n\treturn &clientConn{\n\t\treader:          bufio.NewReader(c),\n\t\twriter:          c,\n\t\tc:               c,\n\t\tstate:           clientStateHandshake,\n\t\thandshakeLock:   sync.Mutex{},\n\t\tprofiles:        profiles,\n\t\tpassword:        password,\n\t\trsaPublicKey:    rsaPublicKey,\n\t\thostname:        hostname,","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/transport/internet/finalmask/xmc/client.go#L28-L64","documentation":"Thrown by newClientConn in the XMC (Minecraft-protocol) transport when the client config's rsa_public_key bytes are empty. The client needs the server's RSA public key both to pin it during the handshake (it must equal the key in the Encryption Request) and to encrypt the shared secret and verify token.","triggerScenarios":"Creating an XMC client connection with Config.RsaPublicKey nil or empty (config.pb.go field rsa_public_key). The check is the first thing newClientConn does, so the connection fails before any I/O.","commonSituations":"Omitting rsa_public_key from the outbound config; copying the server config block to the client side and dropping the key; generating the server key pair but pasting only the private key into the client config.","solutions":["Export the server's public key as DER/PKIX bytes and set rsa_public_key on the client config.","Confirm you copied the public (not private) key and that base64 decoding produced non-empty bytes.","Verify the server side actually has a key pair configured so both sides agree."],"exampleFix":"// before\n\"rsaPublicKey\": \"\"\n// after\n\"rsaPublicKey\": \"MIIBIjANBgkq...\"","handlingStrategy":"validation","validationCode":"if len(cfg.RsaPublicKey) == 0 {\n\treturn errors.New(\"xmc client requires rsa_public_key (server's PKIX DER public key)\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Fail fast in your config loader when rsa_public_key is missing.","Store the key as raw PKIX DER bytes (or decode base64 before passing) exactly as the server emits it."],"tags":["config","xmc","finalmask","crypto","validation"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}