kubernetes/kops · error

failed to build cloud instance group for instance group %q:

Error message

failed to build cloud instance group for instance group %q: %w

What it means

GetCloudGroups calls buildCloudInstanceGroup for each matched server group; this error is thrown when that builder fails, meaning servers could not be reconciled into a CloudInstanceGroup (e.g. inconsistent member data).

Source

Thrown at upup/pkg/fi/cloudup/hetzner/cloud.go:336

	for name, serverGroup := range serverGroups {
		var instanceGroup *kops.InstanceGroup
		for _, ig := range instanceGroups {
			groupName := fmt.Sprintf("%s-%s", cluster.Name, ig.Name)
			if name == groupName {
				instanceGroup = ig
				break
			}
		}
		if instanceGroup == nil {
			if warnUnmatched {
				klog.Warningf("Server group %q has no corresponding instance group", name)
			}
			continue
		}

		cloudInstanceGroups[instanceGroup.Name], err = buildCloudInstanceGroup(instanceGroup, serverGroup, nodeMap)
		if err != nil {
			return nil, fmt.Errorf("failed to build cloud instance group for instance group %q: %w", instanceGroup.Name, err)
		}
	}

	return cloudInstanceGroups, nil
}

// findServerGroups finds all server groups belonging to the cluster
func findServerGroups(c *hetznerCloudImplementation, clusterName string) (map[string][]*hcloud.Server, error) {
	servers, err := c.GetServers(clusterName)
	if err != nil {
		return nil, fmt.Errorf("failed to list servers: %w", err)
	}

	serverGroups := make(map[string][]*hcloud.Server)
	for _, server := range servers {
		instanceGroupNameLabel, ok := server.Labels[TagKubernetesInstanceGroup]
		if !ok {
			klog.Warningf("failed to find instance group name for server %s(%d)", server.Name, server.ID)

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Inspect the wrapped buildCloudInstanceGroup error for the offending server/node
  2. Reconcile drift: kops rolling-update --cloud-labels or recreate mismatched instances
  3. Verify node names in the cluster match Hetzner server names used in nodeMap
  4. Run kops validate to identify and remove orphaned/mislabelled servers
Defensive patterns

Strategy: validation

Validate before calling

// before GetCloudGroups, verify each server maps to a known node or instance group
for _, s := range servers {
	if _, ok := nodeMap[s.Name]; !ok {
		klog.Warningf("server %q has no matching node", s.Name)
	}
}

Type guard

func groupMatches(name string, clusterName string, igs []*kops.InstanceGroup) *kops.InstanceGroup {
	for _, ig := range igs {
		if name == clusterName+"-"+ig.Name {
			return ig
		}
	}
	return nil
}

Try / catch

groups, err := cloud.GetCloudGroups(cluster, igs, warnUnmatched, nodes)
if err != nil {
	return fmt.Errorf("get cloud groups: %w", err)
}
for name, g := range groups {
	if g == nil || len(g.Members) == 0 {
		klog.Warningf("group %q built with no members; check state drift", name)
	}
}

Prevention

When it happens

Trigger: buildCloudInstanceGroup returning an error while mapping servers/nodes, typically when a server in the group cannot be converted to a CloudInstance (bad or missing member metadata).

Common situations: Cluster state drift: servers with duplicated or empty instance-group labels, nodes deregistered or renamed so the nodeMap no longer matches server names, or partially deleted instances after an interrupted rolling update.

Related errors


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