kubernetes/kops · error

failed to convert server ID %q to int: %w

Error message

failed to convert server ID %q to int: %w

What it means

VerifyToken strips the "hcloud://"-style prefix from the presented bootstrap token and parses the remainder as the numeric Hetzner server ID. If the token body isn't a valid int64, parsing fails and the token is rejected. This means the presented token is malformed for this verifier.

Source

Thrown at upup/pkg/fi/cloudup/hetzner/verifier.go:71

		hcloud.WithApplication("kops", version.Version),
	}
	hcloudClient := hcloud.NewClient(opts...)

	return &hetznerVerifier{
		opt:    *opt,
		client: hcloudClient,
	}, nil
}

func (h hetznerVerifier) VerifyToken(ctx context.Context, rawRequest *http.Request, token string, body []byte) (*bootstrap.VerifyResult, error) {
	if !strings.HasPrefix(token, hetznermetadata.HetznerAuthenticationTokenPrefix) {
		return nil, bootstrap.ErrNotThisVerifier
	}
	token = strings.TrimPrefix(token, hetznermetadata.HetznerAuthenticationTokenPrefix)

	serverID, err := strconv.ParseInt(token, 10, 64)
	if err != nil {
		return nil, fmt.Errorf("failed to convert server ID %q to int: %w", token, err)
	}
	server, _, err := h.client.Server.GetByID(ctx, serverID)
	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)))
		}
	}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Regenerate the token on the Hetzner node using the hetznermetadata authenticator (ensure instance metadata works there).
  2. Log/inspect the presented token (after prefix) to see why it isn't numeric.
  3. Ensure the node uses the Hetzner bootstrap authenticator matching this verifier.
  4. Check for token truncation/corruption in whatever passes the token (config, header).
Defensive patterns

Strategy: type-guard

Validate before calling

body := strings.TrimPrefix(token, hetznermetadata.HetznerAuthenticationTokenPrefix)
if _, err := strconv.ParseInt(body, 10, 64); err != nil {
  return nil, bootstrap.ErrNotThisVerifier // malformed: not a Hetzner token
}

Type guard

func isHetznerToken(token string) bool {
  body := strings.TrimPrefix(token, hetznermetadata.HetznerAuthenticationTokenPrefix)
  _, err := strconv.ParseInt(body, 10, 64)
  return err == nil && body != ""
}

Prevention

When it happens

Trigger: A node presents a token whose payload after the prefix is non-numeric (empty, truncated, from a different verifier/provider, or manually forged/edited).

Common situations: Token generated on a non-Hetzner environment (metadata lookup failed earlier and produced a bad token); token truncated in transport; using a token from a different kOps cloud provider.

Related errors


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