{"record":{"id":"cf624b00c1303ca8","repo":"kubernetes/kops","slug":"challenge-endpoint-not-set","errorCode":null,"errorMessage":"challenge.endpoint not set","messagePattern":"challenge\\.endpoint not set","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/bootstrap/challenge_client.go","lineNumber":80,"sourceCode":"\t\tLeaf:        certificate.Certificate,\n\t}\n\treturn clientCertificate, nil\n}\n\nfunc (c *ChallengeClient) DoCallbackChallenge(ctx context.Context, clusterName string, targetEndpoint string, bootstrapRequest *nodeup.BootstrapRequest) error {\n\tchallenge := bootstrapRequest.Challenge\n\n\tif challenge == nil {\n\t\treturn fmt.Errorf(\"challenge not set\")\n\t}\n\tif challenge.ChallengeID == \"\" {\n\t\treturn fmt.Errorf(\"challenge.id not set\")\n\t}\n\tif len(challenge.ChallengeSecret) == 0 {\n\t\treturn fmt.Errorf(\"challenge.secret not set\")\n\t}\n\tif challenge.Endpoint == \"\" {\n\t\treturn fmt.Errorf(\"challenge.endpoint not set\")\n\t}\n\tif len(challenge.ServerCA) == 0 {\n\t\treturn fmt.Errorf(\"challenge.ca not set\")\n\t}\n\n\tclientCertificate, err := c.getClientCertificate(ctx, clusterName)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tserverCAs := x509.NewCertPool()\n\tif !serverCAs.AppendCertsFromPEM(challenge.ServerCA) {\n\t\treturn fmt.Errorf(\"error loading certificate pool\")\n\t}\n\n\tserverName := challengeServerHostName(clusterName)\n\ttlsConfig := &tls.Config{\n\t\tRootCAs:      serverCAs,","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/bootstrap/challenge_client.go#L62-L98","documentation":"DoCallbackChallenge requires a non-empty Endpoint: the host:port of the kops-controller callback server it must dial over gRPC. An empty Endpoint means the challenge configuration is incomplete, so the client cannot know where to send the challenge response and fails fast during validation.","triggerScenarios":"Calling DoCallbackChallenge with a Challenge whose Endpoint field is the empty string — the callback server address was never populated in the challenge config.","commonSituations":"The kops-controller endpoint was not recorded in the node bootstrap configuration; cluster DNS/service discovery misconfiguration left the controller address blank; hand-built Challenge structs omitting Endpoint.","solutions":["Set Challenge.Endpoint to the kops-controller callback address (e.g. <name>.internal.<cluster>) before calling DoCallbackChallenge","Regenerate the challenge/bootstrap config so the controller endpoint is included","Verify the cluster configuration includes the correct kops-controller service address"],"exampleFix":"// before\nch := &bootstrap.Challenge{ChallengeID: id, ChallengeSecret: secret, ServerCA: ca}\n// after\nch := &bootstrap.Challenge{ChallengeID: id, ChallengeSecret: secret, Endpoint: \"kops-controller.internal.example.cluster\", ServerCA: ca}","handlingStrategy":"validation","validationCode":"if ch == nil || ch.Endpoint == \"\" {\n\treturn fmt.Errorf(\"challenge endpoint missing before DoCallbackChallenge\")\n}","typeGuard":null,"tryCatchPattern":"if err := client.DoCallbackChallenge(ctx, clusterName, ch); err != nil {\n\tif strings.Contains(err.Error(), \"challenge.endpoint not set\") {\n\t\t// resolve kops-controller address and rebuild challenge\n\t}\n\treturn err\n}","preventionTips":["Derive the endpoint from cluster configuration rather than hand-editing configs","Validate all challenge fields together in one preflight check"],"tags":["bootstrap","validation","missing-config"],"backgroundTag":"missing-required-argument","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}