kubernetes/kops · error
cannot determine challenge endpoint for server %d
Error message
cannot determine challenge endpoint for server %d
What it means
VerifyToken builds challenge endpoints only from the server's private-network interfaces (server.PrivateNet); Hetzner intentionally does not challenge over the public network. If the server has no private network attachment (or none of the attachments carry an IP), no challenge endpoint can be determined and this error is thrown, blocking node bootstrap verification.
Source
Thrown at upup/pkg/fi/cloudup/hetzner/verifier.go:92
if err != nil || server == nil {
return nil, fmt.Errorf("failed to get info for server %q: %w", token, err)
}
var addrs []string
var challengeEndpoints []string
if server.PublicNet.IPv4.IP != nil {
// Don't challenge over the public network
addrs = append(addrs, server.PublicNet.IPv4.IP.String())
}
for _, network := range server.PrivateNet {
if network.IP != nil {
addrs = append(addrs, network.IP.String())
challengeEndpoints = append(challengeEndpoints, net.JoinHostPort(network.IP.String(), strconv.Itoa(wellknownports.NodeupChallenge)))
}
}
if len(challengeEndpoints) == 0 {
return nil, fmt.Errorf("cannot determine challenge endpoint for server %d", serverID)
}
result := &bootstrap.VerifyResult{
NodeName: server.Name,
CertificateNames: addrs,
ChallengeEndpoint: challengeEndpoints[0],
}
for key, value := range server.Labels {
if key == TagKubernetesInstanceGroup {
result.InstanceGroupName = value
}
}
return result, nil
}
View on GitHub (pinned to 4c8573c808)
Solutions
- Attach the server to the cluster's Hetzner private network (hcloud server attach-to-network or recreate via kOps) so it has a private IP.
- Ensure the cluster spec includes a Hetzner network so new nodes are attached at creation time, then re-run the node bootstrap.
- Verify the network attachment completed and the interface received an IP in the Hetzner console/API before retrying verification.
Defensive patterns
Strategy: validation
Validate before calling
srv, _, err := client.Server.GetByID(ctx, serverID)
if err != nil || srv == nil {
return fmt.Errorf("server %d not reachable: %v", serverID, err)
}
if len(srv.PrivateNet) == 0 {
return fmt.Errorf("server %d has no private network attachment; attach it to the cluster network before bootstrapping", serverID)
} Type guard
func hasChallengeEndpoint(s *hcloud.Server) bool {
for _, n := range s.PrivateNet {
if n.IP != nil { return true }
}
return false
} Prevention
- Always create kOps Hetzner clusters with a network so nodes are attached automatically
- Never detach a node from its private network while nodeup tokens are pending verification
- Verify the private-net IP is assigned in the Hetzner console after attaching a server
When it happens
Trigger: The Hetzner server presenting the bootstrap token is not attached to any private network (hcloud_network_attachment), or the attachment exists but the interface has no assigned IP, so len(challengeEndpoints)==0.
Common situations: Cluster provisioned without a Hetzner network (networking configured with public IPs only); server removed from the network while nodeup still holds a valid token; kOps clusters upgraded to challenge-based bootstrap before the network was attached.
Related errors
- cannot determine challenge endpoint for instance id: %s
- failed to get info for server %q: %w
- failed to find load-balancer %q public address
- failed to find load-balancer %q private address
- failed to find network for loadbalancer %q
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/96eb619b28888b6d.
Report an issue: GitHub.