{"record":{"id":"fe3625b489d68423","repo":"rustdesk/rustdesk","slug":"key-mismatch","errorCode":null,"errorMessage":"Key mismatch","messagePattern":"Key mismatch","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/client.rs","lineNumber":955,"sourceCode":"                    crate::get_next_nonkeyexchange_msg(&mut socket, Some(timeout_ms)).await\n                else {\n                    break;\n                };\n                match msg_in.union {\n                    Some(rendezvous_message::Union::PunchHoleResponse(ph)) => {\n                        if ph.socket_addr.is_empty() {\n                            if !ph.other_failure.is_empty() {\n                                bail!(ph.other_failure);\n                            }\n                            match ph.failure.enum_value() {\n                                Ok(punch_hole_response::Failure::ID_NOT_EXIST) => {\n                                    bail!(\"ID does not exist\");\n                                }\n                                Ok(punch_hole_response::Failure::OFFLINE) => {\n                                    bail!(\"Remote desktop is offline\");\n                                }\n                                Ok(punch_hole_response::Failure::LICENSE_MISMATCH) => {\n                                    bail!(\"Key mismatch\");\n                                }\n                                Ok(punch_hole_response::Failure::LICENSE_OVERUSE) => {\n                                    bail!(\"Key overuse\");\n                                }\n                                _ => bail!(\"other punch hole failure\"),\n                            }\n                        } else {\n                            peer_nat_type = ph.nat_type();\n                            is_local = ph.is_local();\n                            signed_id_pk = ph.pk.into();\n                            relay_server = ph.relay_server;\n                            peer_addr = AddrMangle::decode(&ph.socket_addr);\n                            feedback = ph.feedback;\n                            webrtc_sdp_answer = ph.webrtc_sdp_answer;\n                            let s = udp.0.take();\n                            if udp_nat_port > 0 && ph.is_udp && s.is_some() {\n                                if let Some(s) = s {\n                                    allow_err!(s.connect(peer_addr).await);","sourceCodeStart":937,"sourceCodeEnd":973,"githubUrl":"https://github.com/rustdesk/rustdesk/blob/91c9fccbb0f7bfe5f11644d5fbdec9b23fa10540/src/client.rs#L937-L973","documentation":"The rendezvous server returned Failure::LICENSE_MISMATCH in the PunchHoleResponse, meaning the client's configured public key does not match the key the (pro) server expects. The client bails with 'Key mismatch'.","triggerScenarios":"PunchHoleResponse with empty socket_addr and ph.failure == LICENSE_MISMATCH; the client's 'key' option doesn't match the server's license-bound public key.","commonSituations":"Self-hosted pro server whose license key differs from the key distributed in client configs; server license re-issued without updating clients; mixing public-server clients with a private pro server.","solutions":["Update the client's server 'key' setting to the current key exported from the pro server","Re-deploy/re-import the server config (QR or config string) on clients after any server license change","Verify the server's own license/key files are consistent and restarted cleanly"],"exampleFix":"// before\n\"key\": \"OLD_SERVER_KEY\"\n// after\n\"key\": \"CURRENT_PRO_SERVER_KEY\"","handlingStrategy":"validation","validationCode":"// Ensure the client's configured key matches the pro server's expected key before connecting\nif client_key != expected_server_key { eprintln!(\"Key mismatch: update client server key\"); return; }","typeGuard":null,"tryCatchPattern":"match connect() {\n    Err(e) if e.to_string() == \"Key mismatch\" => {\n        prompt_admin_to_refresh_server_config();\n    }\n    r => handle(r),\n}","preventionTips":["Re-deploy server config (QR/config string) to all clients whenever the server key/license changes","Automate key distribution via MDM/config management instead of manual entry","Keep one canonical source for the server public key"],"tags":["network","license","key","rust"],"backgroundTag":"authentication-required","analyzedSha":"91c9fccbb0f7bfe5f11644d5fbdec9b23fa10540","analyzedAt":"2026-09-10T19:53:44.083Z","contentChangedAt":"2026-09-10T19:53:44.083Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}