kubernetes/kops · error

challenge.ca not set

Error message

challenge.ca not set

What it means

DoCallbackChallenge requires ServerCA to contain the PEM-encoded CA bundle used to authenticate the kops-controller's TLS certificate. An empty ServerCA means the client cannot build the RootCAs pool, so TLS verification of the callback server would be impossible; validation rejects it upfront.

Source

Thrown at pkg/bootstrap/challenge_client.go:83

}

func (c *ChallengeClient) DoCallbackChallenge(ctx context.Context, clusterName string, targetEndpoint string, bootstrapRequest *nodeup.BootstrapRequest) error {
	challenge := bootstrapRequest.Challenge

	if challenge == nil {
		return fmt.Errorf("challenge not set")
	}
	if challenge.ChallengeID == "" {
		return fmt.Errorf("challenge.id not set")
	}
	if len(challenge.ChallengeSecret) == 0 {
		return fmt.Errorf("challenge.secret not set")
	}
	if challenge.Endpoint == "" {
		return fmt.Errorf("challenge.endpoint not set")
	}
	if len(challenge.ServerCA) == 0 {
		return fmt.Errorf("challenge.ca not set")
	}

	clientCertificate, err := c.getClientCertificate(ctx, clusterName)
	if err != nil {
		return err
	}

	serverCAs := x509.NewCertPool()
	if !serverCAs.AppendCertsFromPEM(challenge.ServerCA) {
		return fmt.Errorf("error loading certificate pool")
	}

	serverName := challengeServerHostName(clusterName)
	tlsConfig := &tls.Config{
		RootCAs:      serverCAs,
		Certificates: []tls.Certificate{*clientCertificate},
		ServerName:   serverName,
	}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Populate Challenge.ServerCA with the cluster CA certificate PEM bytes before calling
  2. Re-generate the bootstrap configuration so it embeds the cluster CA
  3. Check where the challenge is persisted/loaded and ensure the CA field is serialized

Example fix

// before
ch := &bootstrap.Challenge{ChallengeID: id, ChallengeSecret: secret, Endpoint: ep}
// after
ch := &bootstrap.Challenge{ChallengeID: id, ChallengeSecret: secret, Endpoint: ep, ServerCA: caBundlePEM}
Defensive patterns

Strategy: validation

Validate before calling

if ch == nil || len(ch.ServerCA) == 0 {
	return fmt.Errorf("challenge ServerCA missing before DoCallbackChallenge")
}
if !bytes.Contains(ch.ServerCA, []byte("-----BEGIN CERTIFICATE-----")) {
	return fmt.Errorf("ServerCA is not PEM")
}

Try / catch

if err := client.DoCallbackChallenge(ctx, clusterName, ch); err != nil {
	if strings.Contains(err.Error(), "challenge.ca not set") {
		// reload CA bundle from cluster pki and retry
	}
	return err
}

Prevention

When it happens

Trigger: Calling DoCallbackChallenge with a Challenge whose ServerCA slice is empty — the cluster CA PEM data was never attached to the challenge configuration.

Common situations: Node bootstrap config missing the cluster CA bundle; a stripped-down or hand-crafted Challenge struct; reading challenge data from a store that dropped the CA bytes.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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