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

  1. Confirm the file is a private key: head -1 should show -----BEGIN ... PRIVATE KEY----- and it must not be the .pub file.
  2. Remove the passphrase or use a keyless copy: ssh-keygen -p -f <key> with an empty new passphrase.
  3. Convert unsupported formats (PuTTY: puttygen key.ppk -O private-openssh -o key.pem).
  4. 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

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


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