rustdesk/rustdesk-server · error
Key pair is INVALID
Error message
Key pair is INVALID
What it means
After both keys construct successfully, validate_keypair signs a fixed test string and verifies it; if `sign::verify` returns Err, the keys do not form a usable Ed25519 signing pair and the code bails with "Key pair is INVALID". Both inputs are individually well-formed but the pair fails the sign/verify round-trip.
Solutions
- Use the secret key and public key from the SAME generated keypair; regenerate the pair together if unsure.
- Compare fingerprints of both keys to confirm they belong together before running validation.
- Replace the deployed key pair on clients with the freshly generated pair after regenerating.
Example fix
// before: mixed pair hbbs --doctor -k '<sk from pair A>' -K '<pk from pair B>' // after: matched pair hbbs --doctor -k '<sk from pair A>' -K '<pk from pair A>'
Defensive patterns
Strategy: validation
Validate before calling
// confirm the pair matches before calling the validator let sig = sign::sign(b"probe", &secret_key); assert!(sign::verify(&sig, &public_key).is_ok(), "secret/public keys do not match");
Try / catch
match validate_keypair(&pk, &sk) {
Err(e) if e.to_string().contains("INVALID") => eprintln!("Keys are not a matched pair - regenerate"),
Err(e) => eprintln!("keypair check failed: {e}"),
Ok(()) => println!("keypair OK"),
} Prevention
- Always regenerate secret and public keys together; never mix across generations.
- Distribute matched keypairs atomically to clients after rotation.
- Keep one keypair directory per server to avoid picking wrong files.
When it happens
Trigger: Signing with secret key A and verifying with an unrelated public key B (mismatched pair), or a corrupted key that decodes to the right length but is cryptographically unusable.
Common situations: Mixing id_ed25519 and id_ed25519.pub from different generations; keys regenerated on the server while old ones are checked; wrong file passed from a directory holding several keypairs.
Understand the failure class
Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.
Related errors
AI-assisted analysis of rustdesk/rustdesk-server@a7736be5e4 (2026-09-09).
Data as JSON: /api/errors/7096bf43fce8235d.
Report an issue: GitHub.
Appendix: source
Thrown at src/utils.rs:64
let secret_key = secret_key.unwrap();
let pk1 = base64::decode(pk);
if pk1.is_err() {
bail!("Invalid public key");
}
let pk1 = pk1.unwrap();
let public_key = sign::PublicKey::from_slice(pk1.as_slice());
if public_key.is_none() {
bail!("Invalid Public key");
}
let public_key = public_key.unwrap();
let random_data_to_test = b"This is meh.";
let signed_data = sign::sign(random_data_to_test, &secret_key);
let verified_data = sign::verify(&signed_data, &public_key);
if verified_data.is_err() {
bail!("Key pair is INVALID");
}
let verified_data = verified_data.unwrap();
if random_data_to_test != &verified_data[..] {
bail!("Key pair is INVALID");
}
Ok(())
}
fn doctor_tcp(address: std::net::IpAddr, port: &str, desc: &str) {
let start = std::time::Instant::now();
let conn = format!("{address}:{port}");
if let Ok(_stream) = TcpStream::connect(conn.as_str()) {
let elapsed = std::time::Instant::now().duration_since(start);
println!(
"TCP Port {} ({}): OK in {} ms",
port,View on GitHub (pinned to a7736be5e4)