rustdesk/rustdesk-server · error
Invalid Secret key
Error message
Invalid Secret key
What it means
After the secret key successfully base64-decodes, validate_keypair feeds the decoded bytes to sign::SecretKey::from_slice; sodium's constructor requires exactly 64 bytes, so if the decoded length is wrong it returns None and the code bails with "Invalid Secret key". The input was valid base64 but not a valid Ed25519 secret key.
Solutions
- Ensure you pass the SECRET key (decodes to exactly 64 bytes) to -k, not the public key.
- Check decoded length: `echo '<sk>' | base64 -d | wc -c` must print 64.
- Regenerate the keypair with the bundled key generator and use the freshly printed 'Secret Key' value.
Example fix
// before: public key (32 bytes) passed as secret hbbs --doctor -k 'OeVuKk5nlHiXp+ApNYY=...' // 32-byte pk // after: the 64-byte secret key hbbs --doctor -k '<64-byte-base64-secret-key>'
Defensive patterns
Strategy: validation
Validate before calling
let decoded = base64::decode(sk.trim())?;
assert_eq!(decoded.len(), 64, "Ed25519 secret key must decode to 64 bytes, got {}", decoded.len()); Type guard
fn is_secret_key_b64(s: &str) -> bool { base64::decode(s).map(|b| b.len() == 64).unwrap_or(false) } Prevention
- Label key files clearly (secret vs public) and never swap CLI flags.
- Check decoded length (64) before invoking the validator.
- Store keys in fixed-format files and read them rather than pasting.
When it happens
Trigger: Supplying a base64 string that decodes to a byte length other than 64 - e.g. a public key (32 bytes) pasted where the secret key belongs, a hex-encoded key, or a truncated key.
Common situations: Swapping the -k (secret) and -p/-K (public) arguments; using a key from a different library/format (hex instead of base64); truncated paste of a 64-byte key.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
AI-assisted analysis of rustdesk/rustdesk-server@a7736be5e4 (2026-09-09).
Data as JSON: /api/errors/cc3a5c3eb6775a6a.
Report an issue: GitHub.
Appendix: source
Thrown at src/utils.rs:44
fn gen_keypair() {
let (pk, sk) = sign::gen_keypair();
let public_key = base64::encode(pk);
let secret_key = base64::encode(sk);
println!("Public Key: {public_key}");
println!("Secret Key: {secret_key}");
}
fn validate_keypair(pk: &str, sk: &str) -> ResultType<()> {
let sk1 = base64::decode(sk);
if sk1.is_err() {
bail!("Invalid secret key");
}
let sk1 = sk1.unwrap();
let secret_key = sign::SecretKey::from_slice(sk1.as_slice());
if secret_key.is_none() {
bail!("Invalid Secret key");
}
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);View on GitHub (pinned to a7736be5e4)