kubernetes/kops · error
error parsing SSH public key: %v
Error message
error parsing SSH public key: %v
What it means
After decoding, the blob is handed to golang.org/x/crypto/ssh.ParsePublicKey; if the SSH wire-format structure is invalid (bad key type string, wrong field counts, malformed mpints, failed signature/geometry checks) the error is wrapped as 'error parsing SSH public key: %v'.
Source
Thrown at pkg/pki/sshkey.go:50
// parseSSHPublicKey parses the SSH public key string
func parseSSHPublicKey(publicKey string) (ssh.PublicKey, error) {
tokens := strings.Fields(publicKey)
if len(tokens) < 2 {
return nil, fmt.Errorf("error parsing SSH public key: %q", publicKey)
}
sshPublicKeyBytes, err := base64.StdEncoding.DecodeString(tokens[1])
if err != nil {
return nil, fmt.Errorf("error decoding SSH public key: %q err: %s", publicKey, err)
}
if len(tokens) < 2 {
return nil, fmt.Errorf("error decoding SSH public key: %q", publicKey)
}
sshPublicKey, err := ssh.ParsePublicKey(sshPublicKeyBytes)
if err != nil {
return nil, fmt.Errorf("error parsing SSH public key: %v", err)
}
return sshPublicKey, nil
}
// colonSeparatedHex formats the byte slice SSH-fingerprint style: hex bytes separated by colons
func colonSeparatedHex(data []byte) string {
sshKeyFingerprint := fmt.Sprintf("%x", data)
var colonSeparated bytes.Buffer
for i := 0; i < len(sshKeyFingerprint); i++ {
if (i%2) == 0 && i != 0 {
colonSeparated.WriteByte(':')
}
colonSeparated.WriteByte(sshKeyFingerprint[i])
}
return colonSeparated.String()
}
View on GitHub (pinned to 4c8573c808)
Solutions
- Regenerate or re-export the public key with `ssh-keygen` and verify `ssh-keygen -l -f id_rsa.pub` succeeds
- Ensure the full single line (type + blob + optional comment) is preserved without internal line breaks
- If using an SSH certificate, extract the underlying public key first
Defensive patterns
Strategy: validation
Validate before calling
func validateSSHPubKey(s string) error {
f := strings.Fields(s)
if len(f) < 2 {
return fmt.Errorf("missing type/blob fields")
}
b, err := base64.StdEncoding.DecodeString(f[1])
if err != nil {
return fmt.Errorf("bad base64: %w", err)
}
if _, err := ssh.ParsePublicKey(b); err != nil {
return fmt.Errorf("bad SSH wire format: %w", err)
}
return nil
}
if err := validateSSHPubKey(pubKey); err != nil {
return err
}
fp, err := pki.ComputeOpenSSHKeyFingerprint(pubKey) Type guard
func isPlainKeyNotCert(pubKey string) bool {
return !strings.Contains(pubKey, "-cert-v01@openssh.com")
} Try / catch
fp, err := pki.ComputeOpenSSHKeyFingerprint(pubKey)
var parseErr *ssh.PassphraseMissingError // example narrowing if using ssh lib directly
if err != nil {
return fmt.Errorf("cannot fingerprint key: %w", err)
} Prevention
- Round-trip check with `ssh-keygen -l -f` before feeding keys to kops
- Keep public keys as single lines without internal wrapping
- Prefer standard ssh-keygen output over hand-assembled key strings
When it happens
Trigger: The base64 blob decodes but is not a well-formed SSH public key: random base64 data, an SSH certificate where a plain key is required, a wire blob from a different key format, or a corrupted/truncated key file.
Common situations: Keys mangled by editors (line wrapping inserted into the blob), users generating keys with exotic formats, or passing an ssh-ed25519 certificate (ssh-ed25519-cert-v01@openssh.com) to fingerprinting code expecting a plain key.
Related errors
- parsing private key %q: %v
- error parsing SSH public key: %q
- error decoding SSH public key: %q err: %s
- method DeleteSSHCredential not supported in server-side clie
- method AddSSHPublicKey not supported in server-side client
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/f1e98b18f6d68ef7.
Report an issue: GitHub.