kubernetes/kops · error
reading private key %q: %v
Error message
reading private key %q: %v
What it means
When toolbox dump is asked to use a private key (for SSH bastion tunneling), it first reads the key file from disk. This error wraps any os.ReadFile failure — missing file, permission denied, or path issues — with the resolved path and the underlying OS error.
Source
Thrown at cmd/kops/toolbox_dump.go:164
resourceMap, err := resourceops.ListResources(cloud, cluster)
if err != nil {
return err
}
d, err := resources.BuildDump(ctx, cloud, resourceMap)
if err != nil {
return err
}
cloudResources = d
}
if options.Dir != "" {
privateKeyPath := options.PrivateKey
if strings.HasPrefix(privateKeyPath, "~/") {
privateKeyPath = filepath.Join(os.Getenv("HOME"), privateKeyPath[2:])
}
key, err := os.ReadFile(privateKeyPath)
if err != nil {
return fmt.Errorf("reading private key %q: %v", privateKeyPath, err)
}
parsedKey, err := ssh.ParseRawPrivateKey(key)
if err != nil {
return fmt.Errorf("parsing private key %q: %v", privateKeyPath, err)
}
signer, err := ssh.NewSignerFromKey(parsedKey)
if err != nil {
return fmt.Errorf("creating signer for private key %q: %v", privateKeyPath, err)
}
contextName := cluster.ObjectMeta.Name
clientGetter := genericclioptions.NewConfigFlags(true)
clientGetter.Context = &contextName
var nodes corev1.NodeList
View on GitHub (pinned to 4c8573c808)
Solutions
- Check the resolved path printed in the error exists: ls -la <path>.
- Fix file permissions: chmod 600 <keyfile> and ensure your user owns it.
- Set HOME correctly (or pass an absolute path) when running under cron/CI where ~ cannot expand.
- Pass the private key file, not the .pub counterpart, and confirm the underlying OS error (No such file vs permission denied) before further steps.
Example fix
// before kops toolbox dump --name c.k8s.local --private-key ~/keys/id_rsa # HOME unset -> path '/keys/id_rsa' missing // after kops toolbox dump --name c.k8s.local --private-key /home/me/keys/id_rsa chmod 600 /home/me/keys/id_rsa
Defensive patterns
Strategy: validation
Validate before calling
KEY_PATH="${KEY_PATH/#\~/$HOME}"
if [ ! -f "$KEY_PATH" ]; then echo "private key not found: $KEY_PATH"; exit 1; fi
if [ ! -r "$KEY_PATH" ]; then echo "private key unreadable (check perms/owner)"; exit 1; fi Try / catch
key, err := os.ReadFile(privateKeyPath)
if err != nil {
return fmt.Errorf("reading private key %q (check path, permissions, HOME): %w", privateKeyPath, err)
} Prevention
- Use absolute paths for keys in CI/cron where $HOME may differ
- chmod 600 the key and ensure your user owns it
- Never point at the .pub file or a directory
- Verify with ssh -i "$KEY_PATH" -o BatchMode=yes host true before running dump
When it happens
Trigger: --private-key (options.PrivateKey) is set, the path is expanded (~/*), and os.ReadFile fails: the file does not exist at the resolved path, the user lacks read permission, or the path is a directory.
Common situations: Passing a path that only exists on another machine; the '~' expansion fails because $HOME is unset in cron/CI; permissions tightened by SSH tooling (600 on a key owned by another user); pointing at the .pub file or a directory instead of the private key.
Related errors
- must specify %q label with cluster name to create SSHCredent
- spec.PublicKey is required
- error reading SSH key file %q: %v
- error reading SSH public key files %q: %v
- error reading SSH public key %v: %v
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/e96bf5aa89a0a8be.
Report an issue: GitHub.