kubernetes/kops · error
SSH key task has unexpected type %T
Error message
SSH key task has unexpected type %T
What it means
Returned by HCloudSSHKey when the first task of type "SSHKey" in the task map is not actually a *hetznertasks.SSHKey. TasksByType matches by type name string, so a different task type registered under the same name (or a custom/wrapped SSHKey implementation) triggers this type-assertion failure.
Source
Thrown at upup/pkg/fi/cloudup/template_functions.go:1270
// Strip the trailing newline that json.Encoder.Encode appends.
return strings.TrimRight(buf.String(), "\n"), nil
}
// HCloudSSHKey returns HCLOUD_SSH_KEY as the first SSH key ID.
func (tf *TemplateFunctions) HCloudSSHKey() (string, error) {
tasks, err := tf.TasksByType("SSHKey")
if err != nil {
return "", fmt.Errorf("listing SSH key tasks: %w", err)
}
if len(tasks) == 0 {
return "", nil
}
// Use the first SSH key, since the autoscaler accepts a single HCLOUD_SSH_KEY.
sshKey, ok := tasks[0].(*hetznertasks.SSHKey)
if !ok {
return "", fmt.Errorf("SSH key task has unexpected type %T", tasks[0])
}
if sshKey.ID != nil {
return strconv.FormatInt(fi.ValueOf(sshKey.ID), 10), nil
}
return "", nil
}
// HCloudClusterConfigChecksum returns a sha256 checksum of the rendered JSON config.
func (tf *TemplateFunctions) HCloudClusterConfigChecksum() (string, error) {
jsonConfig, err := tf.HCloudClusterConfig()
if err != nil {
return "", err
}
sum256 := sha256.Sum256([]byte(jsonConfig))
return fmt.Sprintf("%x", sum256), nilView on GitHub (pinned to 4c8573c808)
Solutions
- Log %T of the offending task to see its actual concrete type
- Ensure only *hetznertasks.SSHKey from the hetznertasks package is registered as an SSHKey task
- Remove wrappers/mocks from the production task map
- Align vendored hetzner task package versions with kops
Example fix
// before: custom wrapper registered as SSHKey
tasks["SSHKey"] = &mySSHKeyWrapper{...}
// after
var key *hetznertasks.SSHKey = &hetznertasks.SSHKey{Name: fi.PtrTo("default"), ...}
tasks["SSHKey"] = key Defensive patterns
Strategy: type-guard
Validate before calling
tasks, err := tf.TasksByType("SSHKey")
if err != nil { return err }
if len(tasks) > 0 {
if _, ok := tasks[0].(*hetznertasks.SSHKey); !ok {
return fmt.Errorf("SSHKey task is %T, not *hetznertasks.SSHKey", tasks[0])
}
} Type guard
func isHetznerSSHKey(t fi.Task) (*hetznertasks.SSHKey, bool) {
key, ok := t.(*hetznertasks.SSHKey)
return key, ok
} Try / catch
sshKeyID, err := tf.HCloudSSHKey()
if err != nil {
return fmt.Errorf("ssh key type mismatch: %w", err)
} Prevention
- Never register wrapper/mock types under the SSHKey task name in production builds
- Keep hetznertasks package versions in sync with kops
- Add unit tests asserting concrete task types after refactorings
- Log %T when type assertions fail to speed diagnosis
When it happens
Trigger: A task registered with type name "SSHKey" is of a concrete type other than *hetznertasks.SSHKey — e.g. a vendored/renamed SSHKey type, a wrapper struct, or a mock leaking into the build.
Common situations: Forking or wrapping hetznertasks.SSHKey and forgetting to keep the registered type; test doubles injected into the task map; kops/hetzner provider version drift where the task type moved packages.
Related errors
- unexpected kind for cluster, got %T, want kops.Cluster
- unexpected target type for deletion: %T
- server group task for instance group %q has unexpected type
- marshaling cluster config: %w
- listing SSH key tasks: %w
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/827a36b55289777c.
Report an issue: GitHub.