kubernetes/kops · error

error converting public key to x509: %w

Error message

error converting public key to x509: %w

What it means

computeKeyID derives a key identifier by marshaling the signer's public key to x509 PKIX form (then PEM/SHA hashing). MarshalPKIXPublicKey fails if the underlying public key type is unsupported by the standard library. NewAuthenticator surfaces this when the signer passed in has an exotic or nil public key.

Source

Thrown at pkg/bootstrap/pkibootstrap/pkisigner.go:76

	Audience string `json:"audience,omitempty"`
}

var _ bootstrap.Authenticator = &pkiAuthenticator{}

func NewAuthenticator(hostname string, signer crypto.Signer) (bootstrap.Authenticator, error) {
	keyID, err := computeKeyID(signer)
	if err != nil {
		return nil, err
	}

	return &pkiAuthenticator{hostname: hostname, signer: signer, keyID: keyID}, nil
}

func computeKeyID(signer crypto.Signer) (string, error) {
	publicKey := signer.Public()
	pkData, err := x509.MarshalPKIXPublicKey(publicKey)
	if err != nil {
		return "", fmt.Errorf("error converting public key to x509: %w", err)
	}

	var b bytes.Buffer
	if err := pem.Encode(&b, &pem.Block{Type: "PUBLIC KEY", Bytes: pkData}); err != nil {
		return "", fmt.Errorf("error encoding public key: %w", err)
	}
	return b.String(), nil
}

func NewAuthenticatorFromFile(p string) (bootstrap.Authenticator, error) {
	hostname, err := os.Hostname()
	if err != nil {
		return nil, fmt.Errorf("couldn't determine hostname: %w", err)
	}

	keyBytes, err := os.ReadFile(p)
	if err != nil {
		return nil, fmt.Errorf("error reading %q: %w", p, err)

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Use a standard key type (RSA, ECDSA, Ed25519) for the signer passed to NewAuthenticator
  2. Check that the signer is fully initialized and Public() returns a concrete supported key
  3. Upgrade Go if the key uses a newer curve than the toolchain supports
  4. If using an HSM wrapper, export/extract a supported public key representation

Example fix

// before
signer, _ := customPKCS11.Signer(nil) // exotic key type
auth, err := pkibootstrap.NewAuthenticator(cluster, signer)
// after
signer, _ := rsa.GenerateKey(rand.Reader, 2048)
auth, err := pkibootstrap.NewAuthenticator(cluster, signer)
Defensive patterns

Strategy: validation

Validate before calling

pub := signer.Public()
switch pub.(type) {
case *rsa.PublicKey, *ecdsa.PublicKey, ed25519.PublicKey:
default:
	return fmt.Errorf("unsupported public key type %T for authenticator", pub)
}

Try / catch

auth, err := pkibootstrap.NewAuthenticator(cluster, signer)
if err != nil && strings.Contains(err.Error(), "converting public key to x509") {
	// swap in a standard RSA/ECDSA/Ed25519 signer
	return err
}

Prevention

When it happens

Trigger: Calling NewAuthenticator with a crypto.Signer whose Public() returns an unsupported key type (not RSA/ECDSA/Ed25519) or fails, causing x509.MarshalPKIXPublicKey to error.

Common situations: Custom or hardware-backed signer (HSM/PKCS#11 wrapper) exposing an unregistered key type; a nil or incorrectly initialized signer; Go version that doesn't recognize the curve used by the key.

Related errors


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