{"record":{"id":"c48bb0d83f0bb548","repo":"kubernetes/kops","slug":"cluster-name-not-set-in-filldefaults","errorCode":null,"errorMessage":"cluster Name not set in FillDefaults","messagePattern":"cluster Name not set in FillDefaults","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/apis/kops/cluster.go","lineNumber":873,"sourceCode":"func (t *TerraformSpec) IsEmpty() bool {\n\treturn len(t.ProviderExtraConfig) == 0 && len(t.FilesProviderExtraConfig) == 0\n}\n\n// FillDefaults populates default values.\n// This is different from PerformAssignments, because these values are changeable, and thus we don't need to\n// store them (i.e. we don't need to 'lock them')\nfunc (c *Cluster) FillDefaults() error {\n\t// Topology support\n\tif c.Spec.Networking.Topology == nil {\n\t\tc.Spec.Networking.Topology = &TopologySpec{DNS: DNSTypePublic}\n\t}\n\n\tif c.Spec.Channel == \"\" {\n\t\tc.Spec.Channel = DefaultChannel\n\t}\n\n\tif c.ObjectMeta.Name == \"\" {\n\t\treturn fmt.Errorf(\"cluster Name not set in FillDefaults\")\n\t}\n\n\treturn nil\n}\n\n// SharedVPC is a simple helper function which makes the templates for a shared VPC clearer\nfunc (c *Cluster) SharedVPC() bool {\n\treturn c.Spec.Networking.NetworkID != \"\"\n}\n\n// IsKubernetesGTE checks if the version is >= the specified version.\n// It panics if the kubernetes version in the cluster is invalid, or if the version is invalid.\nfunc (c *Cluster) IsKubernetesGTE(version string) bool {\n\tclusterVersion, err := util.ParseKubernetesVersion(c.Spec.KubernetesVersion)\n\tif err != nil || clusterVersion == nil {\n\t\tpanic(fmt.Sprintf(\"error parsing cluster spec.kubernetesVersion %q\", c.Spec.KubernetesVersion))\n\t}\n","sourceCodeStart":855,"sourceCodeEnd":891,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/apis/kops/cluster.go#L855-L891","documentation":"FillDefaults populates unset cluster spec fields (like the default channel) and validates invariants. It returns this error when the cluster's ObjectMeta.Name is empty, because almost every downstream operation (DNS, storage paths, templates) requires a cluster name. This is a config validation failure, not an infrastructure error.","triggerScenarios":"Calling FillDefaults (directly or as part of cluster create/update via kops) on a Cluster object whose metadata.name was never set — e.g. applying a YAML manifest missing the metadata.name field, or constructing a Cluster programmatically without a name.","commonSituations":"Hand-written cluster YAML where metadata.name is absent or misspelled (e.g. nested under spec by mistake); programmatic Cluster construction before validation; tooling that copies a cluster spec but drops metadata.","solutions":["Add metadata.name (a valid DNS name) to your cluster manifest and re-run the command","If building the Cluster in Go, set ObjectMeta.Name before calling FillDefaults","Validate the YAML structure to ensure name is under metadata, not spec"],"exampleFix":"# before\napiVersion: kops.k8s.io/v1alpha2\nkind: Cluster\nspec:\n  kubernetesVersion: 1.28.0\n# after\napiVersion: kops.k8s.io/v1alpha2\nkind: Cluster\nmetadata:\n  name: mycluster.example.com\nspec:\n  kubernetesVersion: 1.28.0","handlingStrategy":"validation","validationCode":"func validateClusterName(c *kops.Cluster) error {\n    if c.ObjectMeta.Name == \"\" {\n        return errors.New(\"cluster metadata.name is required\")\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always set metadata.name in cluster manifests","Validate YAML before kops create/update","Keep name under metadata, not spec"],"tags":["kops","cluster","validation","missing-name"],"backgroundTag":"missing-required-argument","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"}