{"record":{"id":"936bedf091e73583","repo":"kubernetes/kops","slug":"unhandled-loadbalancer-type-q-936bed","errorCode":null,"errorMessage":"unhandled LoadBalancer type %q","messagePattern":"unhandled LoadBalancer type %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/model/gcemodel/api_loadbalancer.go","lineNumber":422,"sourceCode":"\t\t\treturn err\n\t\t}\n\t\t// We always create the internal load balancer also;\n\t\t// it allows us to restrict access to only the nodes.\n\t\tif err := b.createInternalLB(c); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\treturn b.addFirewallRules(c)\n\n\tcase kops.LoadBalancerTypeInternal:\n\t\tif err := b.createInternalLB(c); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\treturn b.addFirewallRules(c)\n\n\tdefault:\n\t\treturn fmt.Errorf(\"unhandled LoadBalancer type %q\", lbSpec.Type)\n\t}\n}\n","sourceCodeStart":404,"sourceCodeEnd":425,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/model/gcemodel/api_loadbalancer.go#L404-L425","documentation":"The GCE API load balancer Build method (pkg/model/gcemodel/api_loadbalancer.go:422) switches on spec.api.loadBalancer.type and only implements the supported cases (e.g. public/internal); any other value falls to the default branch and returns 'unhandled LoadBalancer type'. It is a compile-time-style enum guard ensuring the model never silently skips LB creation.","triggerScenarios":"Building the GCE model for a cluster whose spec.api.loadBalancer.type is not one of the values handled by the switch — usually an empty string (loadBalancer block present but type omitted), or an invalid/foreign enum value pasted into the spec.","commonSituations":"Copy-pasting a loadBalancer block from AWS clusters into a GCP spec; leaving 'type:' blank after editing; schema drift between kOps versions changing the LoadBalancerType enum.","solutions":["Set spec.api.loadBalancer.type to a valid GCP-supported value ('public' or 'internal')","Remove the api.loadBalancer block entirely to use DNS-based endpoints instead","Dump the spec with 'kops get cluster -o yaml' to spot typos, casing, or empty values","After fixing, run 'kops update cluster' to regenerate the GCE LB tasks"],"exampleFix":"// before\napi:\n  loadBalancer:\n    type: \"\"\n// after\napi:\n  loadBalancer:\n    type: internal","handlingStrategy":"validation","validationCode":"t := cluster.Spec.API.LoadBalancer.Type\nswitch t {\ncase kops.LoadBalancerTypePublic, kops.LoadBalancerTypeInternal, \"\":\n\t// \"\" only valid if the whole loadBalancer block is omitted\ndefault:\n\treturn fmt.Errorf(\"GCP: unsupported api.loadBalancer.type %q\", t)\n}","typeGuard":"func supportedGCPAPIType(spec *kops.ClusterSpec) bool {\n\tlb := spec.API.LoadBalancer\n\treturn lb == nil || lb.Type == kops.LoadBalancerTypePublic || lb.Type == kops.LoadBalancerTypeInternal\n}","tryCatchPattern":null,"preventionTips":["Set type: public or type: internal explicitly on GCP clusters","Omit the whole api.loadBalancer block rather than leaving an empty one","Diff cluster specs against a known-good GCP example before applying","Run kops update in dry-run/target=terraform mode to catch model errors early"],"tags":["kops","gcp","load-balancer","configuration"],"backgroundTag":"unhandled-loadbalancer-type","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"}