kubernetes/kops · info
error decoding SSH public key: %q
Error message
error decoding SSH public key: %q
What it means
This branch is a redundant defensive check: after a successful base64 decode of tokens[1] it re-checks len(tokens) < 2 and reports a decode error. Since tokens[1] was just accessed, len(tokens) >= 2 already holds, so in practice this exact message is unreachable dead code; the reachable decode failure is reported by errorIndex 1582.
Source
Thrown at pkg/pki/sshkey.go:45
"reflect"
"strings"
"golang.org/x/crypto/ssh"
)
// 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])View on GitHub (pinned to 4c8573c808)
Solutions
- No runtime action needed; treat occurrences of this message as the base64-decode failure path (see 'error decoding SSH public key: %q err: %s')
- If maintaining the code, remove the redundant len(tokens) < 2 re-check
Example fix
// before
if len(tokens) < 2 {
return nil, fmt.Errorf("error decoding SSH public key: %q", publicKey)
}
// after
// (remove the redundant check; tokens[1] was already accessed safely) Defensive patterns
Strategy: try-catch
Try / catch
// Unreachable defensive branch; treat any decode-shaped error via the reachable path:
if _, err := pki.ComputeAWSKeyFingerprint(pubKey); err != nil {
klog.V(2).Infof("SSH key rejected: %v", err) // covers decode + parse paths
} Prevention
- No runtime defense needed for this dead branch
- Validate keys upstream with ssh-keygen -l to keep the whole parse path clean
When it happens
Trigger: Not reachable at runtime: the preceding base64.DecodeString(tokens[1]) guarantees at least two tokens exist.
Common situations: Seen only while reading the source; it appears in audits of sshkey.go as an apparent copy-paste leftover of the earlier token-length check.
Related errors
- method DeleteSSHCredential not supported in server-side clie
- method AddSSHPublicKey not supported in server-side client
- must specify %q label with cluster name to create SSHCredent
- spec.PublicKey is required
- error reading SSH key file %q: %v
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/8a6796ec2afb294a.
Report an issue: GitHub.