kubernetes/kops · error
parsing private key %q: %v
Error message
parsing private key %q: %v
What it means
After reading the private key file, toolbox dump parses it with ssh.ParseRawPrivateKey. This error wraps a parse failure: the file content is not a recognized PEM private key, the key is encrypted (passphrase-protected keys are not supported by ParseRawPrivateKey), or the file is corrupt/truncated.
Source
Thrown at cmd/kops/toolbox_dump.go:169
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
// TODO: We should use the factory to get the kubeconfig
kubeConfig, err := clientGetter.ToRESTConfig()
if err != nil {
klog.Warningf("cannot load kubeconfig settings for %q: %v", contextName, err)
} else {View on GitHub (pinned to 4c8573c808)
Solutions
- Confirm the file is a private key: head -1 should show -----BEGIN ... PRIVATE KEY----- and it must not be the .pub file.
- Remove the passphrase or use a keyless copy: ssh-keygen -p -f <key> with an empty new passphrase.
- Convert unsupported formats (PuTTY: puttygen key.ppk -O private-openssh -o key.pem).
- Regenerate a fresh unencrypted key (ssh-keygen -t ed25519 -N '') if the file is corrupt.
Example fix
// before kops toolbox dump --private-key id_rsa.enc # passphrase-protected -> parse error // after ssh-keygen -p -f id_rsa.enc # remove passphrase kops toolbox dump --private-key id_rsa.enc
Defensive patterns
Strategy: validation
Validate before calling
head -1 "$KEY_PATH" | grep -q '^-----BEGIN.*PRIVATE KEY-----' || { echo "$KEY_PATH is not a private key (or is the .pub)"; exit 1; }
ssh-keygen -y -P "" -f "$KEY_PATH" >/dev/null || { echo "key is encrypted or unparseable"; exit 1; } Try / catch
parsedKey, err := ssh.ParseRawPrivateKey(key)
if err != nil {
return fmt.Errorf("parsing private key %q (encrypted or unsupported format?): %w; consider 'ssh-keygen -p -f %s' to remove passphrase", privateKeyPath, err, privateKeyPath)
} Prevention
- Keep dump-only keys passphrase-less and 600-permissioned
- Never use PuTTY .ppk; convert to OpenSSH PEM format first
- Sanity-check keys with ssh-keygen -y -f before automation
- Detect the .pub mistake: private keys never end in .pub
When it happens
Trigger: os.ReadFile succeeded but ssh.ParseRawPrivateKey(key) returns an error because the bytes are not a valid unencrypted PEM private key (RSA/ECDSA/Ed25519).
Common situations: Pointing at a passphrase-protected key (ParseRawPrivateKey cannot decrypt); passing a public key (.pub) or a certificate; key generated in an unsupported format (PuTTY .ppk, or new OpenSSH format handled differently by the vendored golang.org/x/crypto version); file truncated by a failed scp/copy.
Related errors
- must specify %q label with cluster name to create SSHCredent
- spec.PublicKey is required
- error reading SSH public key %v: %v
- error adding SSH public key: %v
- use 'kops get sshpublickey' instead
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/d541312c8afa80d8.
Report an issue: GitHub.