{"id":"f66964e36e237465","repo":"rust-lang/cargo","slug":"error-failed-to-validate-host-key","errorCode":null,"errorMessage":"error: failed to validate host key:\n{:#}","messagePattern":"error: failed to validate host key:\n(.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src/sources/git/known_hosts.rs","lineNumber":176,"sourceCode":") -> CargoResult<CertificateCheckStatus> {\n    let Some(host_key) = cert.as_hostkey() else {\n        // Return passthrough for TLS X509 certificates to use whatever validation\n        // was done in git2.\n        return Ok(CertificateCheckStatus::CertificatePassthrough);\n    };\n    // If a nonstandard port is in use, check for that first.\n    // The fallback to check without a port is handled in the HostKeyNotFound handler.\n    let host_maybe_port = match port {\n        Some(port) if port != 22 => format!(\"[{host}]:{port}\"),\n        _ => host.to_string(),\n    };\n    // The error message must be constructed as a string to pass through the libgit2 C API.\n    match check_ssh_known_hosts(gctx, host_key, &host_maybe_port, config_known_hosts) {\n        Ok(()) => {\n            return Ok(CertificateCheckStatus::CertificateOk);\n        }\n        Err(KnownHostError::CheckError(e)) => {\n            anyhow::bail!(\"error: failed to validate host key:\\n{:#}\", e)\n        }\n        Err(KnownHostError::HostKeyNotFound {\n            hostname,\n            key_type,\n            remote_host_key,\n            remote_fingerprint,\n            other_hosts,\n        }) => {\n            // Try checking without the port.\n            if port.is_some()\n                && !matches!(port, Some(22))\n                && check_ssh_known_hosts(gctx, host_key, host, config_known_hosts).is_ok()\n            {\n                return Ok(CertificateCheckStatus::CertificateOk);\n            }\n            let key_type_short_name = key_type.short_name();\n            let key_type_name = key_type.name();\n            let known_hosts_location = user_known_host_location_to_add(diagnostic_home_config);","sourceCodeStart":158,"sourceCodeEnd":194,"githubUrl":"https://github.com/rust-lang/cargo/blob/0e07a155371a6ce88ae53a2c00df940280c09a67/src/sources/git/known_hosts.rs#L158-L194","documentation":"A catch-all from `certificate_check` for `KnownHostError::CheckError(e)` — a low-level failure during SSH host-key validation (e.g. libgit2/git2 returned an error parsing keys, a malformed known_hosts entry, or an I/O error reading the known_hosts file). The `{:#}` formatting surfaces the underlying error chain.","triggerScenarios":"Any `KnownHostError::CheckError` returned by `check_ssh_known_hosts` during a git-over-SSH fetch: unreadable `~/.ssh/known_hosts`, a malformed host-key line, unsupported key type, or a git2 internal error. Reached via the git2 certificate-check callback.","commonSituations":"Corrupted `~/.ssh/known_hosts`; permission errors on the known_hosts file; a key type Cargo's bundled known_hosts logic doesn't parse; SSH library version mismatch; filesystem errors.","solutions":["Inspect the formatted `{:#}` error text for the root cause (parse error, permission denied, etc.).","Fix permissions/ownership of `~/.ssh/known_hosts` (e.g. `chmod 644`).","Remove malformed lines from `~/.ssh/known_hosts` or regenerate it.","Bypass Cargo's SSH handling by setting `net.git-fetch-with-cli = true` to use the system `git` CLI."],"exampleFix":"# before: malformed ~/.ssh/known_hosts\n# after (in .cargo/config.toml)\n[net]\ngit-fetch-with-cli = true","handlingStrategy":"try-catch","validationCode":"# Pre-flight: ensure known_hosts is readable and well-formed:\ntest -r ~/.ssh/known_hosts || echo 'known_hosts unreadable'\nssh-keygen -l -f ~/.ssh/known_hosts >/dev/null 2>&1 || echo 'known_hosts parse error'","typeGuard":null,"tryCatchPattern":"// Wrap cargo git operations and fall back to the CLI on SSH errors:\nlet out = std::process::Command::new(\"cargo\").args([\"fetch\"]).output()?;\nif !out.status.success() {\n    let s = String::from_utf8_lossy(&out.stderr);\n    if s.contains(\"failed to validate host key\") {\n        // fall back to system git which may handle the SSH config\n        std::process::Command::new(\"git\")\n            .args([\"config\", \"--global\", \"credential.helper\", \"store\"]).status()?;\n    }\n}","preventionTips":["Keep `~/.ssh/known_hosts` readable (`chmod 644`) and free of malformed lines.","Set `net.git-fetch-with-cli = true` to delegate SSH to the system git/ssh.","Standardize SSH key types across servers to ones Cargo parses (ed25519, rsa, ecdsa)."],"tags":["ssh","git","host-key","known-hosts","security"],"analyzedSha":"0e07a155371a6ce88ae53a2c00df940280c09a67","analyzedAt":"2026-08-06T01:46:58.334Z","schemaVersion":2}