kubernetes/kops · error

no certificate provided

Error message

no certificate provided

What it means

Keyset.AddItem adds a certificate/private key pair as a KeysetItem. It rejects a nil cert with the plain error 'no certificate provided' before any other validation, because every keyset item is defined by its certificate.

Source

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

}

// 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
	}

	return keyset, nil
}

// AddItem adds an item to the keyset
func (k *Keyset) AddItem(cert *pki.Certificate, privateKey *pki.PrivateKey, primary bool) (item *KeysetItem, err error) {
	if cert == nil {
		return item, fmt.Errorf("no certificate provided")
	}
	if privateKey == nil && primary {
		return item, fmt.Errorf("private key not provided for primary item")
	}

	if !primary && k.Primary == nil {
		return item, fmt.Errorf("cannot add secondary item when no existing primary item")
	}

	highestId := big.NewInt(0)
	for id := range k.Items {
		itemId, ok := big.NewInt(0).SetString(id, 10)
		if ok && highestId.Cmp(itemId) < 0 {
			highestId = itemId
		}
	}

	// Make sure any subsequently created items will have ids that compare higher.

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Fix the caller to load/parse the certificate before AddItem; check the parse error that yielded nil.
  2. Ensure the cert file/resource exists and is valid PEM (openssl x509 -in cert.pem -noout).
  3. If privateKey is passed and primary is true, also supply privateKey — but resolve the nil cert first as it fails earliest.
  4. Wrap cert parsing to fail fast instead of forwarding nil into AddItem.

Example fix

// before
cert, err := pki.ParsePEMCertificate(data) // err ignored, cert==nil
item, err := keyset.AddItem(cert, priv, true)

// after
cert, err := pki.ParsePEMCertificate(data)
if err != nil {
  return nil, fmt.Errorf("parsing certificate: %w", err)
}
if cert == nil {
  return nil, fmt.Errorf("parsed certificate is nil")
}
item, err := keyset.AddItem(cert, priv, true)
Defensive patterns

Strategy: validation

Validate before calling

function assertCertPresent(cert: Certificate | null | undefined, source: string): Certificate {
  if (cert == null) throw new Error("certificate missing for keyset item from " + source)
  return cert
}
keyset.addItem(assertCertPresent(maybeCert, "ca-bundle"), priv, true)

Type guard

function isCert(v: Certificate | null | undefined): v is Certificate {
  return v != null
}

Try / catch

try {
  keyset.addItem(cert, priv, true)
} catch (e) {
  if (/no certificate provided/.test(e.message)) {
    console.error("caller passed nil cert — check upstream parse error")
  }
  throw e
}

Prevention

When it happens

Trigger: NewKeyset -> Keyset.AddItem with cert == nil — the caller passed no certificate while adding to the keyset (privateKey may be present but cert is mandatory).

Common situations: Programmatic callers (provisioning code, tests, tooling that builds keysets) passing a parsed private key but a nil certificate — e.g. cert parsing failed upstream and the nil result was passed through unchecked.

Understand the failure class

Related errors


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