kubernetes/kops · error

error reading SSH public key: %v

Error message

error reading SSH public key: %v

What it means

SSHKey.Normalize in the OpenStack tasks reads the configured SSH public key resource as a string via fi.ResourceAsString and fails when the resource cannot be read or decoded (file missing, unreadable, invalid path, bad bytes). kOps needs the public key text to compute its OpenSSH fingerprint before uploading the keypair to OpenStack.

Source

Thrown at upup/pkg/fi/cloudup/openstacktasks/sshkey.go:77

		KeyFingerprint: new(rs.Fingerprint),
	}

	// Avoid spurious changes
	if fi.ValueOf(actual.KeyFingerprint) == fi.ValueOf(e.KeyFingerprint) {
		klog.V(2).Infof("SSH key fingerprints match; assuming public keys match")
		actual.PublicKey = e.PublicKey
	} else {
		klog.V(2).Infof("Computed SSH key fingerprint mismatch: %q %q", fi.ValueOf(e.KeyFingerprint), fi.ValueOf(actual.KeyFingerprint))
	}
	actual.Lifecycle = e.Lifecycle
	return actual, nil
}

func (e *SSHKey) Normalize(c *fi.CloudupContext) error {
	if e.KeyFingerprint == nil && e.PublicKey != nil {
		publicKey, err := fi.ResourceAsString(e.PublicKey)
		if err != nil {
			return fmt.Errorf("error reading SSH public key: %v", err)
		}

		keyFingerprint, err := pki.ComputeOpenSSHKeyFingerprint(publicKey)
		if err != nil {
			return fmt.Errorf("error computing key fingerprint for SSH key: %v", err)
		}
		klog.V(2).Infof("Computed SSH key fingerprint as %q", keyFingerprint)
		e.KeyFingerprint = &keyFingerprint
	}
	return nil
}

func (e *SSHKey) Run(c *fi.CloudupContext) error {
	return fi.CloudupDefaultDeltaRunMethod(e, c)
}

func (s *SSHKey) CheckChanges(a, e, changes *SSHKey) error {
	if a == nil {

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Verify the public key file exists and is readable: 'cat <path>' — generate one with 'ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519' if missing.
  2. Pass an absolute path: kops update cluster --ssh-public-key /home/user/.ssh/id_ed25519.pub.
  3. Ensure you pass the .pub public key, not the private key file.
  4. Check file permissions (chmod 644 on the public key) and that it is valid OpenSSH one-line format.

Example fix

// before
kops update cluster --name my.cluster --ssh-public-key ~/.ssh/id_rsa
// after (public key, absolute path)
kops update cluster --name my.cluster --ssh-public-key /home/user/.ssh/id_rsa.pub
Defensive patterns

Strategy: validation

Validate before calling

# Validate the SSH public key before running kops
KEY="$HOME/.ssh/id_ed25519.pub"
[ -r "$KEY" ] || { echo "key not readable: $KEY"; exit 1; }
ssh-keygen -lf "$KEY" >/dev/null 2>&1 || { echo "not a valid OpenSSH public key"; exit 1; }

Try / catch

// If driving the task directly
publicKey, err := fi.ResourceAsString(e.PublicKey)
if err != nil {
    return fmt.Errorf("check --ssh-public-key path/readability: %v", err)
}

Prevention

When it happens

Trigger: Normalize is invoked with e.KeyFingerprint == nil and e.PublicKey != nil, and fi.ResourceAsString(e.PublicKey) returns an error — typically the key file path in the cluster spec (--ssh-public-key / sshPublicKey) does not exist or is not readable, or the resource points to an empty/binary file.

Common situations: Running 'kops update cluster --ssh-public-key ~/.ssh/id_rsa.pub' where the file was never generated; a typo'd or relative path with wrong working directory; a private key (.pem) passed instead of the .pub; permission errors on the key file; cluster spec referencing a key path from another machine.

Related errors


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