kubernetes/kops · error
error reading SSH key file %q: %v
Error message
error reading SSH key file %q: %v
What it means
During `kops create cluster`, if --ssh-public-key was provided, loadSSHPublicKeys(sshPublicKey) is called to read and parse the key file; a read failure is wrapped as 'error reading SSH key file'. It means the file could not be opened or read from disk.
Source
Thrown at cmd/kops/create_cluster.go:222
RunE: func(cmd *cobra.Command, args []string) error {
var err error
if cmd.Flag("associate-public-ip").Changed {
options.AssociatePublicIP = &associatePublicIP
}
if cmd.Flag("encrypt-etcd-storage").Changed {
options.EncryptEtcdStorage = &encryptEtcdStorage
}
if err := checkProjectFlag(cmd.Flag("project").Changed, options.Project); err != nil {
return err
}
if sshPublicKey != "" {
options.SSHPublicKeys, err = loadSSHPublicKeys(sshPublicKey)
if err != nil {
return fmt.Errorf("error reading SSH key file %q: %v", sshPublicKey, err)
}
}
return RunCreateCluster(cmd.Context(), f, out, options)
},
}
cmd.Flags().BoolVarP(&options.Yes, "yes", "y", options.Yes, "Specify --yes to immediately create the cluster")
cmd.Flags().Var(&options.Target, "target", fmt.Sprintf("Valid targets: %q, %q. Set this flag to %q if you want kOps to generate terraform", cloudup.TargetDirect, cloudup.TargetTerraform, cloudup.TargetTerraform))
cmd.RegisterFlagCompletionFunc("target", completeCreateClusterTarget(options))
// Configuration / state location
if featureflag.EnableSeparateConfigBase.Enabled() {
cmd.Flags().StringVar(&options.ConfigBase, "config-base", options.ConfigBase, "A cluster-readable location where we mirror configuration information, separate from the state store. Allows for a state store that is not accessible from the cluster.")
cmd.RegisterFlagCompletionFunc("config-base", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
// TODO complete vfs paths
return nil, cobra.ShellCompDirectiveNoFileComp
})View on GitHub (pinned to 4c8573c808)
Solutions
- Verify the path passed to --ssh-public-key exists and points to a .pub public key file
- Check file permissions (must be readable by the current user)
- Use an absolute path in CI/containers where the working directory or HOME differs
- Pass an empty value or omit the flag to skip SSH key loading
Example fix
// before kops create cluster --ssh-public-key ~/.ssh/id_rsa ... // after kops create cluster --ssh-public-key ~/.ssh/id_rsa.pub ...
Defensive patterns
Strategy: validation
Validate before calling
func validateSSHPublicKey(path string) error {
if path == "" { return nil }
fi, err := os.Stat(path)
if err != nil { return fmt.Errorf("ssh key not found: %w", err) }
if fi.IsDir() { return fmt.Errorf("%s is a directory", path) }
data, err := os.ReadFile(path)
if err != nil { return err }
if !strings.HasPrefix(string(data), "ssh-") {
return fmt.Errorf("%s does not look like a public key", path)
}
return nil
} Prevention
- Always pass the .pub file, never the private key
- Use absolute paths in scripts and CI
- Check the file exists before running kops create cluster
- Mount SSH keys into CI containers explicitly
When it happens
Trigger: Passing --ssh-public-key with a path that does not exist, is a directory, or lacks read permissions when building CreateClusterOptions before RunCreateCluster is invoked.
Common situations: Typo in the key path; using ~/.ssh/id_rsa (private key) instead of the .pub file; running in CI where the key file wasn't mounted; wrong HOME so ~ expansion fails.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- error reading SSH public key files %q: %v
- error reading SSH key file %q: %v
- error reading file %q: %v
- must specify %q label with cluster name to create SSHCredent
- spec.PublicKey is required
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/19532bc1ba93b210.
Report an issue: GitHub.