rustdesk/rustdesk · error

Key mismatch

Error message

Key mismatch

What it means

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'.

Source

Thrown at src/client.rs:955

                    crate::get_next_nonkeyexchange_msg(&mut socket, Some(timeout_ms)).await
                else {
                    break;
                };
                match msg_in.union {
                    Some(rendezvous_message::Union::PunchHoleResponse(ph)) => {
                        if ph.socket_addr.is_empty() {
                            if !ph.other_failure.is_empty() {
                                bail!(ph.other_failure);
                            }
                            match ph.failure.enum_value() {
                                Ok(punch_hole_response::Failure::ID_NOT_EXIST) => {
                                    bail!("ID does not exist");
                                }
                                Ok(punch_hole_response::Failure::OFFLINE) => {
                                    bail!("Remote desktop is offline");
                                }
                                Ok(punch_hole_response::Failure::LICENSE_MISMATCH) => {
                                    bail!("Key mismatch");
                                }
                                Ok(punch_hole_response::Failure::LICENSE_OVERUSE) => {
                                    bail!("Key overuse");
                                }
                                _ => bail!("other punch hole failure"),
                            }
                        } else {
                            peer_nat_type = ph.nat_type();
                            is_local = ph.is_local();
                            signed_id_pk = ph.pk.into();
                            relay_server = ph.relay_server;
                            peer_addr = AddrMangle::decode(&ph.socket_addr);
                            feedback = ph.feedback;
                            webrtc_sdp_answer = ph.webrtc_sdp_answer;
                            let s = udp.0.take();
                            if udp_nat_port > 0 && ph.is_udp && s.is_some() {
                                if let Some(s) = s {
                                    allow_err!(s.connect(peer_addr).await);

View on GitHub (pinned to 91c9fccbb0)

Solutions

  1. Update the client's server 'key' setting to the current key exported from the pro server
  2. Re-deploy/re-import the server config (QR or config string) on clients after any server license change
  3. Verify the server's own license/key files are consistent and restarted cleanly

Example fix

// before
"key": "OLD_SERVER_KEY"
// after
"key": "CURRENT_PRO_SERVER_KEY"
Defensive patterns

Strategy: validation

Validate before calling

// Ensure the client's configured key matches the pro server's expected key before connecting
if client_key != expected_server_key { eprintln!("Key mismatch: update client server key"); return; }

Try / catch

match connect() {
    Err(e) if e.to_string() == "Key mismatch" => {
        prompt_admin_to_refresh_server_config();
    }
    r => handle(r),
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of rustdesk/rustdesk@91c9fccbb0 (2026-09-10). Data as JSON: /api/errors/fe3625b489d68423. Report an issue: GitHub.