kubernetes/kops · error
error reading public key %q: %w
Error message
error reading public key %q: %w
What it means
buildHostData reads the target's SSH public key (default /root/.ssh/id_ed25519.pub style path) over SSH. If the read fails with any error other than fs.ErrNotExist — e.g. permission denied, connection reset mid-transfer — the command wraps it as "error reading public key %q".
Source
Thrown at pkg/commands/toolbox_enroll.go:179
}
if err := enrollHost(ctx, fullInstanceGroup, bootstrapData, restConfig, hostData, sshTarget); err != nil {
return err
}
return nil
}
// buildHostData builds an instance of the Host CRD, based on information in the options and by SSHing to the target host.
func buildHostData(ctx context.Context, sshTarget *SSHHost, options *ToolboxEnrollOptions) (*v1alpha2.Host, error) {
publicKeyPath := "/etc/kubernetes/kops/pki/machine/public.pem"
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))
View on GitHub (pinned to 4c8573c808)
Solutions
- Check the wrapped error: fix permissions on the remote key file (`chmod 600 ~/.ssh/id_ed25519; chmod 700 ~/.ssh`) or make it readable by the SSH user
- Pre-create a readable public key on the host, or let kops create it by ensuring the key simply does not exist (then it generates one)
- Verify SSH connectivity and user: `ssh -p <port> <user>@<host> 'cat <path>'`
Example fix
// on the target host, before enrolling // before: -rw------- root root /root/.ssh/id_ed25519.pub read via non-root user // after chmod 755 /root/.ssh && chmod 644 /root/.ssh/id_ed25519.pub
Defensive patterns
Strategy: try-catch
Validate before calling
ssh -p "$PORT" "$USER@$HOST" 'test -r ~/.ssh/id_ed25519.pub || test ! -e ~/.ssh/id_ed25519.pub' \
|| { echo "public key exists but is not readable by SSH user"; exit 1; } Try / catch
err := RunToolboxEnroll(ctx, f, out, opts)
if err != nil && strings.Contains(err.Error(), "error reading public key") {
log.Printf("fix remote key permissions or SSH user; cause: %v", err)
return err
} Prevention
- Enroll as root or ensure the SSH user can read the key path
- Standardize permissions: 700 ~/.ssh, 644 *.pub on targets
- Test `ssh <host> cat <keypath>` before running enroll
When it happens
Trigger: The remote key file exists but is unreadable by the SSH user; SFTP/SSH channel errors; the path is a directory; transient network failure during readFile.
Common situations: Enrolling hosts where the SSH user isn't root (default is root, but custom configs differ) and cannot read /root/.ssh; hardened images with restrictive permissions on .ssh; flaky networks.
Related errors
- error reading public key %q (after creation): %w
- error reading SSH public key: %v
- error building metal node identifier: %w
- creating metal IPAM controller: %w
- method DeleteSSHCredential not supported in server-side clie
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/a69c41a13bb0af8f.
Report an issue: GitHub.