kubernetes/kops · error

error reading public key %q (after creation): %w

Error message

error reading public key %q (after creation): %w

What it means

When the public key does not exist, kops runs a script on the target to generate a keypair, then re-reads the public key. If that second read fails (the creation script ran but the file still isn't readable/present), this distinct error tells you generation itself didn't produce a usable key.

Source

Thrown at pkg/commands/toolbox_enroll.go:192

	publicKeyBytes, err := sshTarget.readFile(ctx, publicKeyPath)
	if err != nil {
		if errors.Is(err, fs.ErrNotExist) {
			publicKeyBytes = nil
		} else {
			return nil, fmt.Errorf("error reading public key %q: %w", publicKeyPath, err)
		}
	}

	// Create the key if it doesn't exist
	publicKeyBytes = bytes.TrimSpace(publicKeyBytes)
	if len(publicKeyBytes) == 0 {
		if _, err := sshTarget.runScript(ctx, scriptCreateKey, ExecOptions{Echo: true}); err != nil {
			return nil, err
		}

		b, err := sshTarget.readFile(ctx, publicKeyPath)
		if err != nil {
			return nil, fmt.Errorf("error reading public key %q (after creation): %w", publicKeyPath, err)
		}
		publicKeyBytes = b
	}
	klog.Infof("public key is %s", string(publicKeyBytes))

	hostname, err := sshTarget.getHostname(ctx)
	if err != nil {
		return nil, err
	}

	host := &v1alpha2.Host{}
	host.SetGroupVersionKind(v1alpha2.SchemeGroupVersion.WithKind("Host"))
	host.Namespace = "kops-system"
	host.Name = hostname
	host.Spec.InstanceGroup = options.InstanceGroup
	host.Spec.PublicKey = string(publicKeyBytes)
	host.Spec.PodCIDRs = options.PodCIDRs

View on GitHub (pinned to 4c8573c808)

Solutions

  1. SSH into the host and run the keygen manually (`ssh-keygen -t ed25519 -N '' -f ~/.ssh/id_ed25519`) to see the real failure
  2. Install/repair ssh-keygen on the target (e.g. `apt-get install openssh-client`)
  3. Ensure /root/.ssh exists, is writable, and the keygen output path matches what kops expects

Example fix

// on the target host
// before: bash: ssh-keygen: command not found
// after
apt-get update && apt-get install -y openssh-client
Defensive patterns

Strategy: validation

Validate before calling

ssh -p "$PORT" root@$HOST 'command -v ssh-keygen >/dev/null && [ -w ~/.ssh ]' \
  || { echo "target cannot generate keys: install openssh-client and ensure ~/.ssh is writable"; exit 1; }

Try / catch

if err := RunToolboxEnroll(...); err != nil && strings.Contains(err.Error(), "after creation") {
    log.Printf("key auto-generation failed on target; create the key manually: %v", err)
    return err
}

Prevention

When it happens

Trigger: ssh-keygen missing or failing on the target (so no .pub file appears), the creation script writing to a different path than publicKeyPath, or read failures right after creation (permissions, SFTP errors).

Common situations: Minimal OS images without openssh-keygen/ssh-keygen installed; read-only /root/.ssh; SELinux or immutable /etc/ssh preventing key generation.

Related errors


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