kubernetes/kops · error

error parsing SSH public key: %v

Error message

error parsing SSH public key: %v

What it means

AddSSHPublicKey validates the supplied key with golang.org/x/crypto/ssh.ParseAuthorizedKey before storing it. If the bytes are not a valid OpenSSH authorized_keys entry, it returns 'error parsing SSH public key: %v'. kOps never persists unparseable keys.

Source

Thrown at upup/pkg/fi/clientset_castore.go:301

	}
	return nil
}

// deleteSSHCredential deletes the SSHCredential from the registry.
func (c *ClientsetCAStore) deleteSSHCredential(ctx context.Context) error {
	client := c.clientset.SSHCredentials(c.namespace)
	err := client.Delete(ctx, "admin", metav1.DeleteOptions{})
	if err != nil {
		return fmt.Errorf("error deleting SSHCredential: %v", err)
	}
	return nil
}

// AddSSHPublicKey implements CAStore::AddSSHPublicKey
func (c *ClientsetCAStore) AddSSHPublicKey(ctx context.Context, pubkey []byte) error {
	_, _, _, _, err := ssh.ParseAuthorizedKey(pubkey)
	if err != nil {
		return fmt.Errorf("error parsing SSH public key: %v", err)
	}

	return c.addSSHCredential(ctx, strings.TrimSpace(string(pubkey)))
}

// FindSSHPublicKeys implements CAStore::FindSSHPublicKeys
func (c *ClientsetCAStore) FindSSHPublicKeys() ([]*kops.SSHCredential, error) {
	ctx := context.TODO()

	o, err := c.clientset.SSHCredentials(c.namespace).Get(ctx, "admin", metav1.GetOptions{})
	if err != nil {
		if errors.IsNotFound(err) {
			return nil, nil
		}
		return nil, fmt.Errorf("error reading SSHCredential: %v", err)
	}
	o.Spec.PublicKey = strings.TrimSpace(o.Spec.PublicKey)

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Pass the contents of the .pub file (e.g. ~/.ssh/id_rsa.pub), never the private key
  2. Validate locally: `ssh-keygen -l -f mykey.pub` must succeed
  3. Ensure the file has no CRLF line endings and is a single authorized_keys line
  4. Regenerate the key with `ssh-keygen -t ed25519` if the format is non-standard

Example fix

// before
pub, _ := os.ReadFile("~/.ssh/id_rsa") // private key — parse fails
store.AddSSHPublicKey(ctx, pub)
// after
pub, _ := os.ReadFile("~/.ssh/id_rsa.pub")
if _, _, _, _, err := ssh.ParseAuthorizedKey(pub); err != nil {
	return fmt.Errorf("invalid public key: %w", err)
}
store.AddSSHPublicKey(ctx, pub)
Defensive patterns

Strategy: validation

Validate before calling

func validPublicKey(pub []byte) error {
	if len(pub) == 0 { return errors.New("empty key") }
	if _, _, _, _, err := ssh.ParseAuthorizedKey(pub); err != nil { return err }
	return nil
}
// call before AddSSHPublicKey
if err := validPublicKey(pub); err != nil { return err }

Type guard

func isParsedAuthorizedKey(b []byte) bool {
	_, _, _, _, err := ssh.ParseAuthorizedKey(b)
	return err == nil
}

Try / catch

if err := store.AddSSHPublicKey(ctx, pub); err != nil {
	if strings.Contains(err.Error(), "error parsing SSH public key") {
		return fmt.Errorf("not an authorized_keys-format public key: %w", err)
	}
	return err
}

Prevention

When it happens

Trigger: Passing a private key file, a certificate, an empty/truncated buffer, or text with a broken base64 field to AddSSHPublicKey; also caused by reading the wrong file (e.g. id_rsa instead of id_rsa.pub) or Windows line endings/CRLF in the key file.

Common situations: `kops create sshpublickey` pointed at a private key instead of the .pub file; copy-pasted key losing characters; key generated by a tool producing non-standard formats (e.g. PuTTY PPK not exported to OpenSSH).

Related errors


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