kubernetes/kops · error
error reading user provided private key %q: %v
Error message
error reading user provided private key %q: %v
What it means
In createKeypair, when the user supplies --key, the file is expanded (~) and read from disk with os.ReadFile before parsing. Any OS-level read failure (missing file, permission denied, is-a-directory) is wrapped with this message including the resolved path.
Source
Thrown at cmd/kops/create_keypair.go:193
for name := range keysets {
if rotatableKeysetFilter(name, nil) {
if err := createKeypair(ctx, out, options, name, keyStore); err != nil {
return fmt.Errorf("creating keypair for %s: %v", name, err)
}
}
}
return nil
}
func createKeypair(ctx context.Context, out io.Writer, options *CreateKeypairOptions, name string, keyStore fi.CAStore) error {
var err error
var privateKey *pki.PrivateKey
if options.PrivateKeyPath != "" {
options.PrivateKeyPath = utils.ExpandPath(options.PrivateKeyPath)
privateKeyBytes, err := os.ReadFile(options.PrivateKeyPath)
if err != nil {
return fmt.Errorf("error reading user provided private key %q: %v", options.PrivateKeyPath, err)
}
privateKey, err = pki.ParsePEMPrivateKey(privateKeyBytes)
if err != nil {
return fmt.Errorf("error loading private key %q: %v", privateKeyBytes, err)
}
}
var cert *pki.Certificate
if options.CertPath == "" {
if privateKey == nil {
privateKey, err = pki.GeneratePrivateKey()
if err != nil {
return fmt.Errorf("error generating private key: %v", err)
}
}
serial := pki.BuildPKISerial(time.Now().UnixNano())View on GitHub (pinned to 4c8573c808)
Solutions
- Verify the file exists at the expanded path: ls -l <path>.
- Fix file permissions (chmod so the invoking user can read it).
- Use an absolute path instead of ~ to avoid expansion surprises in CI.
- Check secrets mounting when running inside containers/pipelines.
Example fix
// before kops create keypair cluster.k8s.local --keyset ca --key ~/keys/ca.key # file not there // after ls -l /home/me/keys/ca.key # confirm first kops create keypair cluster.k8s.local --keyset ca --key /home/me/keys/ca.key
Defensive patterns
Strategy: validation
Validate before calling
KEY_PATH=$(readlink -f "${KEY_PATH/#\~/$HOME}")
[[ -f "$KEY_PATH" && -r "$KEY_PATH" ]] || { echo "private key not readable: $KEY_PATH"; exit 1; }
kops create keypair "$CLUSTER" --keyset ca --key "$KEY_PATH" Try / catch
if ! out=$(kops create keypair "$CLUSTER" --keyset ca --key "$KEY" 2>&1); then
case "$out" in
*"error reading user provided private key"*) echo "Check path/permissions: $out";;
esac
fi Prevention
- Use absolute paths for --key in scripts and CI.
- Verify file existence and permissions before invoking kops.
- Mount/copy key material explicitly in containerized runs; don't rely on $HOME.
When it happens
Trigger: `kops create keypair <cluster> --keyset <name> --key <path>` where os.ReadFile(<expanded path>) errors (cmd/kops/create_keypair.go:193).
Common situations: Typo in path; running in container/CI where the key wasn't mounted; wrong $HOME so ~ expansion points elsewhere; file permissions after copying keys between machines.
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
- reading encryption config %v: %v
- error reading SSH public key %v: %v
- reading file %q: %v
- unable to expand the template: %s, error: %s
- unable to expand the snippets: %s, error: %s
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/1edd708f5b659192.
Report an issue: GitHub.