kubernetes/kops · error
expected an AWS cloud, got %T
Error message
expected an AWS cloud, got %T
What it means
karpenterRootDeviceName resolves an AMI's root device name (/dev/xvda, /dev/sda1, etc.) so Karpenter EC2NodeClass block device mappings override the image's root volume. The template function's cloud field must be an awsup.AWSCloud to call ResolveImage; this error is thrown when tf.cloud holds any other cloud implementation or nil, i.e. Karpenter EC2NodeClass generation was attempted on a non-AWS cluster.
Source
Thrown at upup/pkg/fi/cloudup/template_functions_karpenter.go:388
}
return []karpenterBlockDeviceMapping{
{
DeviceName: rootDeviceName,
EBS: ebs,
RootVolume: new(true),
},
}, nil
}
// karpenterRootDeviceName resolves the root device name of the InstanceGroup image, so
// that the generated block device mapping overrides the image's root volume rather than
// attaching an additional one. The name varies between images (/dev/xvda, /dev/sda1),
// so it has to come from the image itself.
func (tf *TemplateFunctions) karpenterRootDeviceName(image string) (string, error) {
cloud, ok := tf.cloud.(awsup.AWSCloud)
if !ok {
return "", fmt.Errorf("expected an AWS cloud, got %T", tf.cloud)
}
resolved, err := cloud.ResolveImage(image)
if err != nil {
return "", fmt.Errorf("unable to resolve image %q: %w", image, err)
}
if resolved == nil {
return "", fmt.Errorf("unable to resolve image %q: not found", image)
}
rootDeviceName := fi.ValueOf(resolved.RootDeviceName)
if rootDeviceName == "" {
return "", fmt.Errorf("image %q has no root device name", image)
}
return rootDeviceName, nil
}
func (tf *TemplateFunctions) buildKarpenterNodePool(ig *kops.InstanceGroup) (*karpenterNodePool, error) {
labels, err := nodelabels.BuildNodeLabels(tf.Cluster, ig)
if err != nil {View on GitHub (pinned to 4c8573c808)
Solutions
- Ensure the cluster's cloudProvider is aws before using providerRole/karpenter instance groups
- Check the cluster spec: cloudConfig.aws should be configured and `kops get cluster -oyaml` should show cloudProvider aws
- Move the Karpenter instance group to an AWS-only cluster, or use the cloud's native autoscaling instead
- If writing tests, inject a mock or real awsup.AWSCloud into tf.cloud
Example fix
// before (non-AWS cluster spec)
cloudProvider: gce
instanceGroups: [{ name: karpenter-ig, karpenter: {...} }]
// after
cloudProvider: aws
# or remove the karpenter instance group on non-AWS clusters Defensive patterns
Strategy: type-guard
Validate before calling
// before using karpenter template functions
if _, ok := tf.cloud.(awsup.AWSCloud); !ok {
return fmt.Errorf("karpenter requires AWS; cluster cloud is %T", tf.cloud)
} Type guard
func isAWSCloud(c fi.Cloud) bool {
_, ok := c.(awsup.AWSCloud)
return ok
} Try / catch
// Go: check the error returned by the template function
rootDev, err := tf.karpenterRootDeviceName(image)
if err != nil {
if strings.Contains(err.Error(), "expected an AWS cloud") {
return fmt.Errorf("karpenter is AWS-only: %w", err)
}
return err
} Prevention
- Only enable karpenter instance groups on clusters with cloudProvider: aws
- Gate Karpenter template rendering behind a cluster cloud check early in updateCluster
- Add a unit test asserting non-AWS clusters never reach buildKarpenterEC2NodeClass
When it happens
Trigger: Running `kops update cluster` with an InstanceGroup using the Karpenter provider on a cluster whose cloud is not AWS (GCE, DO, Hetzner, OpenStack, Azure), or tf.cloud being nil/uninitialized when buildKarpenterEC2NodeClass invokes karpenterRootDeviceName.
Common situations: Copy-pasting a cluster config with karpenterInstanceGroups from an AWS cluster into a non-AWS cluster; forgetting to set cloudProvider/aws on the cluster spec; unit tests constructing TemplateFunctions without an AWSCloud (as in TestKarpenterRootDeviceNameWithoutAWSCloud).
Related errors
- error identifying node %q: %v
- error building node identifier: %w
- unexpected target type for deletion: %T
- unexpected target type for deletion: %T
- unexpected target type for deletion: %T
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/54761e6eaf53739b.
Report an issue: GitHub.