kubernetes/kops · error

error encoding ECDSA private key

Error message

error encoding ECDSA private key: %w

What it means

PrivateKey.WriteTo marshals ECDSA keys with x509.MarshalECPrivateKey; if that fails (the DER serialization of the EC key cannot be produced) it returns 'error encoding ECDSA private key'. This happens when the ecdsa.PrivateKey has fields that cannot round-trip through SEC1 DER.

Solutions

  1. Check the wrapped x509 error to see which part of the EC key failed to marshal.
  2. Verify the ecdsa.PrivateKey was produced by a standard generator (ecdsa.GenerateKey / x509.ParseECPrivateKey), not hand-assembled.
  3. Regenerate the EC key or switch to RSA (pki.GeneratePrivateKey) so encoding is guaranteed to work.

Example fix

// before
k := &pki.PrivateKey{Key: &ecdsa.PrivateKey{PublicKey: pub}} // missing D
// after
key, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
k := &pki.PrivateKey{Key: key}
Defensive patterns

Strategy: validation

Validate before calling

ec, ok := key.Key.(*ecdsa.PrivateKey)
if !ok {
    return fmt.Errorf("not an ECDSA key")
}
if ec.D == nil {
    return fmt.Errorf("ECDSA key missing private scalar D; regenerate")
}

Type guard

func validECKey(k *pki.PrivateKey) bool {
    ec, ok := k.Key.(*ecdsa.PrivateKey)
    return ok && ec.D != nil
}

Try / catch

s, err := key.AsString()
if err != nil {
    if strings.Contains(err.Error(), "error encoding ECDSA private key") {
        // regenerate EC key with ecdsa.GenerateKey
    }
    return err
}

Prevention

When it happens

Trigger: Calling WriteTo (or AsString/AsBytes/MarshalJSON/WriteToFile) on a PrivateKey whose Key is an *ecdsa.PrivateKey that x509.MarshalECPrivateKey rejects — e.g. a key constructed manually with an unusual curve or nil D value.

Common situations: Keys deserialized from non-standard sources; manually assembled ecdsa.PrivateKey structs missing D; custom curves not supported by the stdlib SEC1 encoder.

Related errors


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

Appendix: source

Thrown at pkg/pki/privatekey.go:162

var _ io.WriterTo = &PrivateKey{}

func (k *PrivateKey) WriteTo(w io.Writer) (int64, error) {
	if k.Key == nil {
		// For the dry-run case
		return 0, nil
	}

	var data bytes.Buffer

	switch pk := k.Key.(type) {
	case *rsa.PrivateKey:
		if err := pem.Encode(&data, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(pk)}); err != nil {
			return 0, fmt.Errorf("error encoding RSA private key: %w", err)
		}
	case *ecdsa.PrivateKey:
		b, err := x509.MarshalECPrivateKey(pk)
		if err != nil {
			return 0, fmt.Errorf("error encoding ECDSA private key: %w", err)
		}
		if err := pem.Encode(&data, &pem.Block{Type: "EC PRIVATE KEY", Bytes: b}); err != nil {
			return 0, fmt.Errorf("error encoding ECDSA private key: %w", err)
		}
	default:
		return 0, fmt.Errorf("unknown private key type: %T", k.Key)
	}

	return data.WriteTo(w)
}

func (k *PrivateKey) WriteToFile(filename string, perm os.FileMode) error {
	f, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
	if err != nil {
		return err
	}
	_, err = k.WriteTo(f)
	if err1 := f.Close(); err == nil {

View on GitHub (pinned to 4c8573c808)