kubernetes/kops · error

error decoding SSH public key: %q err: %s

Error message

error decoding SSH public key: %q err: %s

What it means

After the type token, parseSSHPublicKey base64-decodes the second whitespace field; failure here means the blob is not valid base64. The error includes the offending key string and the decode error from base64.StdEncoding.

Source

Thrown at pkg/pki/sshkey.go:42

	"crypto/x509"
	"encoding/base64"
	"fmt"
	"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 {

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Regenerate/obtain the key from `ssh-keygen -y -f id_rsa > id_rsa.pub` and use that exact line
  2. Check the base64 blob for embedded whitespace or non-standard characters
  3. Verify you're not passing a PEM-formatted (-----BEGIN PUBLIC KEY-----) key where an OpenSSH-format pub key is expected

Example fix

// before
// passing body of a PEM PUBLIC KEY block
fp, _ := ComputeAWSKeyFingerprint(pemBodyBase64)
// after
pubBytes, _ := os.ReadFile("~/.ssh/id_rsa.pub") // OpenSSH one-line format
fp, _ := ComputeAWSKeyFingerprint(string(pubBytes))
Defensive patterns

Strategy: validation

Validate before calling

func blobIsBase64(pubKey string) bool {
	f := strings.Fields(pubKey)
	if len(f) < 2 {
		return false
	}
	_, err := base64.StdEncoding.DecodeString(f[1])
	return err == nil
}
if !blobIsBase64(pubKey) {
	return fmt.Errorf("second field of SSH public key is not valid standard base64")
}

Try / catch

if _, err := pki.ComputeOpenSSHKeyFingerprint(pubKey); err != nil {
	if strings.Contains(err.Error(), "error decoding SSH public key") {
		// base64 blob invalid: ask user to re-export the key
	}
}

Prevention

When it happens

Trigger: The second token contains characters outside the standard base64 alphabet (e.g. the key was double-encoded, URL-safe base64 was used, or PEM body lines were pasted instead of the OpenSSH wire blob), or the blob is truncated mid-line.

Common situations: Pasting the body of a PEM public key (which is DER base64, not the SSH wire format), or copy/paste introducing newlines/spaces inside the blob field.

Related errors


AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05). Data as JSON: /api/errors/2afc9b71650b0f80. Report an issue: GitHub.