rustdesk/rustdesk · critical

WebRTC peer identity could not be verified (refusing unbound

Error message

WebRTC peer identity could not be verified (refusing unbound channel)

What it means

In secure_connection(), if the SignedId payload cannot be decoded/verified under the trusted signing key (the outer `else` of the decode), a non-WebRTC transport falls back to a non-secure connection. A WebRTC transport cannot safely do that without identity binding, so it refuses the unbound channel and raises this error instead.

Source

Thrown at src/client.rs:1678

                                    create_symmetric_key_msg(their_pk_b);
                                let mut msg_out = Message::new();
                                msg_out.set_public_key(PublicKey {
                                    asymmetric_value,
                                    symmetric_value,
                                    ..Default::default()
                                });
                                timeout(CONNECT_TIMEOUT, conn.send(&msg_out)).await??;
                                conn.set_key(key);
                            } else {
                                if is_webrtc {
                                    bail!("WebRTC handshake id mismatch (possible MITM)");
                                }
                                log::error!("Handshake failed: sign failure");
                                conn.send(&Message::new()).await?;
                            }
                        } else {
                            if is_webrtc {
                                bail!("WebRTC peer identity could not be verified (refusing unbound channel)");
                            }
                            // fall back to non-secure connection in case pk mismatch
                            log::info!("pk mismatch, fall back to non-secure");
                            let mut msg_out = Message::new();
                            msg_out.set_public_key(PublicKey::new());
                            conn.send(&msg_out).await?;
                        }
                    } else {
                        if is_webrtc {
                            bail!("WebRTC handshake received an unexpected message type");
                        }
                        log::error!("Handshake failed: invalid message type");
                        conn.send(&Message::new()).await?;
                    }
                } else {
                    if is_webrtc {
                        bail!("WebRTC handshake received a malformed message");
                    }

View on GitHub (pinned to 91c9fccbb0)

Solutions

  1. Align the client's configured `key` with the server's actual signing public key
  2. Upgrade the remote peer/client to compatible versions so SignedId verifies
  3. Verify rendezvous/relay infrastructure integrity (tampering produces unverifiable blobs)
  4. Retry after server key rotation completes on both ends

Example fix

// before
--key <stale-key>
// after
--key <current server signing key> // SignedId then verifies and WebRTC channel is bound
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-check that a signing key is configured so SignedId can verify
if get_rs_pk(key).is_none() {
    eprintln!("No valid signing key: WebRTC identity verification will refuse the channel");
}

Try / catch

match Client::connect(...).await {
    Err(e) if e.to_string().contains("peer identity could not be verified") => {
        // fix key config / versions before retrying
    }
    r => r?,
}

Prevention

When it happens

Trigger: `is_webrtc` is true and `decode_id_pk_dtls(&si.id, &sign_pk)` failed (or an earlier arm left identity unverified) — the peer's signed identity blob did not verify under the configured rs_pk/sign_pk.

Common situations: Client key mismatch with the server's signing key; corrupted SignedId payload from a relay; peer running incompatible crypto or a tampered server; MITM replacing the SignedId blob.

Related errors


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