{"record":{"id":"4a6913d20146e778","repo":"kubernetes/kops","slug":"image-q-has-no-root-device-name","errorCode":null,"errorMessage":"image %q has no root device name","messagePattern":"image %q has no root device name","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/template_functions_karpenter.go","lineNumber":399,"sourceCode":"// karpenterRootDeviceName resolves the root device name of the InstanceGroup image, so\n// that the generated block device mapping overrides the image's root volume rather than\n// attaching an additional one. The name varies between images (/dev/xvda, /dev/sda1),\n// so it has to come from the image itself.\nfunc (tf *TemplateFunctions) karpenterRootDeviceName(image string) (string, error) {\n\tcloud, ok := tf.cloud.(awsup.AWSCloud)\n\tif !ok {\n\t\treturn \"\", fmt.Errorf(\"expected an AWS cloud, got %T\", tf.cloud)\n\t}\n\tresolved, err := cloud.ResolveImage(image)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"unable to resolve image %q: %w\", image, err)\n\t}\n\tif resolved == nil {\n\t\treturn \"\", fmt.Errorf(\"unable to resolve image %q: not found\", image)\n\t}\n\trootDeviceName := fi.ValueOf(resolved.RootDeviceName)\n\tif rootDeviceName == \"\" {\n\t\treturn \"\", fmt.Errorf(\"image %q has no root device name\", image)\n\t}\n\treturn rootDeviceName, nil\n}\n\nfunc (tf *TemplateFunctions) buildKarpenterNodePool(ig *kops.InstanceGroup) (*karpenterNodePool, error) {\n\tlabels, err := nodelabels.BuildNodeLabels(tf.Cluster, ig)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"building node labels for %q: %w\", ig.Name, err)\n\t}\n\tlabels = karpenterNodePoolTemplateLabels(labels)\n\n\ttemplate := karpenterNodeClaimTemplate{\n\t\tSpec: karpenterNodeClaimSpec{\n\t\t\tRequirements: tf.karpenterRequirements(ig),\n\t\t\tNodeClassRef: karpenterNodeClassRef{\n\t\t\t\tGroup: karpenterAWSAPIGroup,\n\t\t\t\tKind:  \"EC2NodeClass\",\n\t\t\t\tName:  ig.Name,","sourceCodeStart":381,"sourceCodeEnd":417,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/template_functions_karpenter.go#L381-L417","documentation":"The AMI resolved fine but its RootDeviceName field was empty, so kops cannot generate a root-volume block device mapping for the Karpenter EC2NodeClass. The root device name is required to override the image's root volume instead of attaching an extra volume.","triggerScenarios":"cloud.ResolveImage returns a non-nil ec2.Image whose RootDeviceName is unset — typically an anomalous/incomplete DescribeImages response or an image with no block device mappings.","commonSituations":"Rare: corrupted/edge-case AMI metadata, custom-built images lacking rootDeviceName in their block device mappings, or AWS API returning a partial image record.","solutions":["Verify the AMI's block device mappings with `aws ec2 describe-images` — rootDeviceName should be set","Choose a different/standard AMI that declares a root device","Re-run kops update cluster in case of a transient partial API response","If it is a custom AMI, rebuild it with a proper root EBS mapping"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// check rootDeviceName before rendering\nimg, err := cloud.ResolveImage(image)\nif err == nil && img != nil && fi.ValueOf(img.RootDeviceName) == \"\" {\n\treturn fmt.Errorf(\"AMI %s has no root device mapping\", image)\n}","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"has no root device name\") {\n\treturn fmt.Errorf(\"choose an AMI with a defined root device: %w\", err)\n}","preventionTips":["Inspect `aws ec2 describe-images` blockDeviceMappings before using a custom AMI","Prefer standard published AMIs (AL2023, Ubuntu) which always declare a root device","Rebuild custom AMIs with a proper root EBS mapping"],"tags":["aws","ec2","ami","block-device","karpenter"],"backgroundTag":"missing-root-device-name","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T07:17:12.445Z"}