kubernetes/kops · error

marshalling public key %s: %v

Error message

marshalling public key %s: %v

What it means

Keyset.ToPublicKeys marshals each keyset item's certificate public key with x509.MarshalPKIXPublicKey into PKIX DER form. If Go's x509 parser rejects the key type/data, it returns 'marshalling public key %s: %v' with the item id — the certificate is loadable but its embedded public key cannot be represented in PKIX (e.g. unsupported algorithm).

Source

Thrown at upup/pkg/fi/ca.go:175

func (k *Keyset) ToPublicKeys() (string, error) {
	keys := make([]string, 0, len(k.Items))
	for k, item := range k.Items {
		if item.DistrustTimestamp == nil {
			keys = append(keys, k)
		}
	}
	sort.Slice(keys, func(i, j int) bool {
		return KeysetItemIdOlder(k.Items[keys[i]].Id, k.Items[keys[j]].Id)
	})

	buf := new(strings.Builder)
	for _, key := range keys {
		item := k.Items[key]
		if item.Certificate != nil {
			publicKeyData, err := x509.MarshalPKIXPublicKey(item.Certificate.PublicKey)
			if err != nil {
				return "", fmt.Errorf("marshalling public key %s: %v", item.Id, err)
			}
			if err = pem.Encode(buf, &pem.Block{Type: "RSA PUBLIC KEY", Bytes: publicKeyData}); err != nil {
				return "", fmt.Errorf("encoding public key %s: %v", item.Id, err)
			}
		}
	}
	return buf.String(), nil
}

// NewKeyset creates a Keyset.
func NewKeyset(cert *pki.Certificate, privateKey *pki.PrivateKey) (*Keyset, error) {
	keyset := &Keyset{
		Items: map[string]*KeysetItem{},
	}
	_, err := keyset.AddItem(cert, privateKey, true)
	if err != nil {
		return nil, err
	}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Check the item id in the message and inspect the certificate's algorithm: openssl x509 -text | grep -A2 'Public Key Algorithm'.
  2. Re-issue the certificate with a supported key type (RSA 2048+ or ECDSA P-256/P-384).
  3. Rotate the affected keyset item so a standards-compliant cert becomes primary.
  4. Upgrade/downgrade Go (x509 algorithm support changes between Go versions) if the cert is intentionally unusual.
  5. Verify the cert parses fully in Go before storing it in the keyset.

Example fix

// before: storing an exotic-algorithm cert in the keyset
// after: re-issue with a supported key
openssl req -x509 -newkey rsa:2048 -nodes -keyout ca.key -out ca.crt -subj "/CN=kops-ca"
Defensive patterns

Strategy: validation

Validate before calling

// reject unsupported key algorithms before storing/using a certificate
$ openssl x509 -in cert.pem -noout -text | grep "Public Key Algorithm"
# accept only: rsaEncryption, id-ecPublicKey (P-256/P-384/P-521), ED25519

Type guard

function isSupportedAlgorithm(alg: string): boolean {
  return ["rsaEncryption", "id-ecPublicKey", "ED25519"].includes(alg)
}

Try / catch

try {
  const pemKeys = keyset.toPublicKeys()
} catch (e) {
  if (/marshalling public key/.test(e.message)) {
    const itemId = e.message.match(/marshalling public key (\S+):/)?.[1]
    console.error("unsupported/invalid public key on item:", itemId)
    // re-issue the cert with RSA/ECDSA and rotate the item
  }
  throw e
}

Prevention

When it happens

Trigger: Keyset.ToPublicKeys: item.Certificate.PublicKey holds a key type MarshalPKIXPublicKey cannot handle (nil PublicKey, DSA/ECDSA-with-odd-params, or a certificate parsed with an unexpected field).

Common situations: Certificates generated by non-Go tooling with exotic algorithms; a certificate whose PublicKey wasn't populated because parsing partially failed upstream; legacy CAs using algorithms Go dropped support for.

Related errors


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