kubernetes/kops · error

unhandled bastion LoadBalancer type %q

Error message

unhandled bastion LoadBalancer type %q

What it means

kops's BastionModelBuilder.Build translates the cluster spec's bastion load balancer type (spec.networking.topology.bastion.loadBalancer.type) into an ELB/NLB scheme string. Only "internal" and "public" are recognized; any other value (including an empty string when the surrounding block expected one to be defaulted) makes the builder abort cluster rendering with this error. It is a spec-validation guard inside the AWS model build phase.

Source

Thrown at pkg/model/awsmodel/bastion.go:112

				Egress:        new(true),
				IPv6CIDR:      new("::/0"),
			}
			AddDirectionalGroupRule(c, t)
		}
	}

	var bastionLoadBalancerType kops.LoadBalancerType
	{
		// Check if we requested a public or internal NLB
		if b.Cluster.Spec.Networking.Topology != nil && b.Cluster.Spec.Networking.Topology.Bastion != nil && b.Cluster.Spec.Networking.Topology.Bastion.LoadBalancer != nil {
			if b.Cluster.Spec.Networking.Topology.Bastion.LoadBalancer.Type != "" {
				switch b.Cluster.Spec.Networking.Topology.Bastion.LoadBalancer.Type {
				case kops.LoadBalancerTypeInternal:
					bastionLoadBalancerType = "Internal"
				case kops.LoadBalancerTypePublic:
					bastionLoadBalancerType = "Public"
				default:
					return fmt.Errorf("unhandled bastion LoadBalancer type %q", b.Cluster.Spec.Networking.Topology.Bastion.LoadBalancer.Type)
				}
			} else {
				// Default to Public
				b.Cluster.Spec.Networking.Topology.Bastion.LoadBalancer.Type = kops.LoadBalancerTypePublic
				bastionLoadBalancerType = "Public"
			}
		} else {
			// Default to Public
			bastionLoadBalancerType = "Public"
		}
	}

	// Allow bastion nodes to SSH to control plane
	for _, src := range bastionGroups {
		for _, dest := range masterGroups {
			t := &awstasks.SecurityGroupRule{
				Name:          new("bastion-to-master-ssh" + JoinSuffixes(src, dest)),
				Lifecycle:     b.SecurityLifecycle,

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Set spec.networking.topology.bastion.loadBalancer.type to exactly "internal" or "public" in the cluster manifest
  2. Remove the loadBalancer.type field entirely so the builder defaults it to "public"
  3. Run `kops edit cluster` (or the editor of your manifest) and fix casing/typos, then re-run `kops update cluster`

Example fix

// before (cluster.yaml)
topology:
  bastion:
    loadBalancer:
      type: Internal
// after
topology:
  bastion:
    loadBalancer:
      type: internal
Defensive patterns

Strategy: validation

Validate before calling

t := cluster.Spec.Networking.Topology.Bastion.LoadBalancer.Type
if t != "" && t != kops.LoadBalancerTypeInternal && t != kops.LoadBalancerTypePublic {
    return fmt.Errorf("invalid bastion loadBalancer.type %q: must be \"internal\" or \"public\"", t)
}

Type guard

func validBastionLBType(t kops.LoadBalancerType) bool {
    return t == kops.LoadBalancerTypeInternal || t == kops.LoadBalancerTypePublic
}

Try / catch

if err := buildModel(ctx); err != nil {
    if strings.Contains(err.Error(), "unhandled bastion LoadBalancer type") {
        return fmt.Errorf("fix spec.networking.topology.bastion.loadBalancer.type (internal|public): %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Running `kops update cluster` (or `kops create cluster --bastion`) where spec.networking.topology.bastion.loadBalancer.type is set to anything other than "internal" or "public" — e.g. a typo like "Internal", "private", or an empty string that bypassed the defaulting branch.

Common situations: Hand-edited cluster manifests, YAML migrated from another tool or older kops version with a now-invalid value, case-sensitivity mistakes (value must be lowercase), or automation templates injecting a wrong default.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05). Data as JSON: /api/errors/e8c5bd8b29f9ae8c. Report an issue: GitHub.