kubernetes/kops · error
callback challenge returned wrong result
Error message
callback challenge returned wrong result
What it means
After a successful RPC, the client compares the server's response bytes to the locally computed expected challenge response using a constant-time comparison. A mismatch means the server returned a different response than the HMAC derived from the ChallengeSecret — indicating the server did not hold the same secret or the challenge data was tampered with.
Source
Thrown at pkg/bootstrap/challenge_client.go:126
expectedChallengeResponse := buildChallengeResponse(challenge.ChallengeSecret, kospControllerNonce)
var opts []grpc.DialOption
opts = append(opts, grpc.WithTransportCredentials(credentials.NewTLS(tlsConfig)))
conn, err := grpc.DialContext(ctx, targetEndpoint, opts...)
if err != nil {
return fmt.Errorf("error dialing target %q: %w", targetEndpoint, err)
}
defer conn.Close()
client := pb.NewCallbackServiceClient(conn)
response, err := client.Challenge(ctx, req)
if err != nil {
return fmt.Errorf("error from callback challenge: %w", err)
}
if subtle.ConstantTimeCompare(response.GetChallengeResponse(), expectedChallengeResponse) != 1 {
return fmt.Errorf("callback challenge returned wrong result")
}
return nil
}
View on GitHub (pinned to 4c8573c808)
Solutions
- Re-run the challenge/bootstrap flow to obtain a fresh challenge and secret from kops-controller
- Verify the ChallengeID and ChallengeSecret pair matches what the server currently holds
- Ensure you are dialing the genuine kops-controller endpoint, not a stale or spoofed address
Example fix
null
Defensive patterns
Strategy: validation
Validate before calling
if len(ch.ChallengeID) == 0 || len(ch.ChallengeSecret) == 0 {
return fmt.Errorf("stale/empty challenge; request a fresh challenge first")
} Try / catch
if err := client.DoCallbackChallenge(ctx, clusterName, ch); err != nil {
if strings.Contains(err.Error(), "wrong result") {
// discard cached challenge, re-request a fresh one, retry once
}
return err
} Prevention
- Never cache challenge secrets across rotations
- Always dial the canonical kops-controller endpoint
- Re-run the challenge handshake on any mismatch instead of retrying the same data
When it happens
Trigger: Calling DoCallbackChallenge when response.GetChallengeResponse() differs from buildChallengeResponse(ChallengeSecret, nonce): wrong/rotated secret on the server, stale challenge ID, or a man-in-the-middle/buggy server returning unexpected bytes.
Common situations: The challenge secret was rotated on the server after issuance to the node; the node cached an old challenge; a misconfigured or malicious callback endpoint answering with wrong material.
Related errors
- keypair is distrusted
- no TLS connection
- no client certificate presented
- failed to verify client certificate chain: %w
- url not valid for STS request
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/a6f1302192846f39.
Report an issue: GitHub.