kubernetes/kops · error
server group task for instance group %q has unexpected type
Error message
server group task for instance group %q has unexpected type %T
What it means
After successfully fetching the ServerGroup task in HCloudClusterConfig, the code type-asserts it to *hetznertasks.ServerGroup. If the task stored under that name is a different type, the assertion fails and this error reports the actual Go type %T found.
Source
Thrown at upup/pkg/fi/cloudup/template_functions.go:1198
NodeConfigs: map[string]hcloudNodeConfig{},
}
for _, ig := range tf.KopsModelContext.InstanceGroups {
if !ig.Spec.Role.HasNode() {
continue
}
if ig.Spec.Autoscale != nil && !fi.ValueOf(ig.Spec.Autoscale) {
continue
}
task, err := tf.Task("ServerGroup", ig.Name)
if err != nil {
return "", fmt.Errorf("finding server group task for instance group %q: %w", ig.Name, err)
}
serverGroup, ok := task.(*hetznertasks.ServerGroup)
if !ok {
return "", fmt.Errorf("server group task for instance group %q has unexpected type %T", ig.Name, task)
}
nodeLabels, err := nodelabels.BuildNodeLabels(tf.Cluster, ig)
if err != nil {
return "", fmt.Errorf("building node labels for instance group %q: %w", ig.Name, err)
}
userDataBytes, err := fi.ResourceAsBytes(serverGroup.UserData)
if err != nil {
return "", fmt.Errorf("reading user-data for instance group %q: %w", ig.Name, err)
}
var taints []corev1.Taint
for _, taintSpec := range ig.Spec.Taints {
parsed, err := util.ParseTaint(taintSpec)
if err != nil {
return "", fmt.Errorf("parsing taints for instance group %q: %w", ig.Name, err)
}View on GitHub (pinned to 4c8573c808)
Solutions
- Ensure the task registered as "ServerGroup" for the instance group is hetznertasks.ServerGroup (use stock Hetzner model templates).
- Sync kOps binary and model/templates to the same version.
- If forking, keep the task type and name consistent with HCloudClusterConfig's assertion.
Example fix
// before (custom template)
task := &hetznertasks.ServerGroupVolume{Name:...}
// after
task := &hetznertasks.ServerGroup{Name:...} Defensive patterns
Strategy: type-guard
Validate before calling
// Go: pre-check the registered task type before use
task, _ := tf.Task("ServerGroup", ig.Name)
if _, ok := task.(*hetznertasks.ServerGroup); !ok && task != nil {
return fmt.Errorf("ServerGroup/%s registered as unexpected %T", ig.Name, task)
} Type guard
// Go
func asServerGroup(t fi.Task) (*hetznertasks.ServerGroup, bool) {
sg, ok := t.(*hetznertasks.ServerGroup)
return sg, ok
} Prevention
- Do not register custom tasks under the built-in "ServerGroup" name
- Rebuild all templates when upgrading the hetznertasks package
- Add CI check asserting task types for each cloud model
When it happens
Trigger: A task named ServerGroup/<ig.Name> exists in the context but was registered by different code/templates as another task type — e.g. custom/overridden Hetzner templates registering a different struct under the same task name.
Common situations: Customized model templates conflicting with built-in task names; running mixed kOps versions (binary newer than templates or vice versa); local forks renaming the task struct.
Related errors
- finding server group task for instance group %q: %w
- SSH key task has unexpected type %T
- unexpected kind for cluster, got %T, want kops.Cluster
- unexpected object type: %T
- failed to get private networks from hetzner cloud metadata:
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/399608d0482ea9e6.
Report an issue: GitHub.