kubernetes/kops · error
unknown topology type: %q
Error message
unknown topology type: %q
What it means
setupAPI configures how the Kubernetes API endpoint is exposed and bases decisions on opt.Topology. Its switch only knows public and private; any other topology value reaching here (after the earlier validation) is rejected with this defensive error while creating the cluster.
Source
Thrown at upup/pkg/fi/cloudup/new_cluster.go:1561
// Populate the API access, so that it can be discoverable
klog.Infof("Cloud Provider ID: %q", cluster.GetCloudProvider())
if opt.APILoadBalancerType != "" || opt.APISSLCertificate != "" {
cluster.Spec.API.LoadBalancer = &api.LoadBalancerAccessSpec{}
} else {
switch opt.Topology {
case api.TopologyPublic:
if cluster.UsesNoneDNS() {
// there are no DNS records for the API, so we use a LoadBalancer instead
cluster.Spec.API.LoadBalancer = &api.LoadBalancerAccessSpec{}
} else {
cluster.Spec.API.DNS = &api.DNSAccessSpec{}
}
case api.TopologyPrivate:
cluster.Spec.API.LoadBalancer = &api.LoadBalancerAccessSpec{}
default:
return fmt.Errorf("unknown topology type: %q", opt.Topology)
}
}
if cluster.Spec.API.LoadBalancer != nil && cluster.Spec.API.LoadBalancer.Type == "" {
switch opt.APILoadBalancerType {
case "", "public":
cluster.Spec.API.LoadBalancer.Type = api.LoadBalancerTypePublic
case "internal":
cluster.Spec.API.LoadBalancer.Type = api.LoadBalancerTypeInternal
default:
return fmt.Errorf("unknown api-loadbalancer-type: %q", opt.APILoadBalancerType)
}
}
if cluster.Spec.API.LoadBalancer != nil && opt.APISSLCertificate != "" {
cluster.Spec.API.LoadBalancer.SSLCertificate = opt.APISSLCertificate
}
View on GitHub (pinned to 4c8573c808)
Solutions
- Set NewClusterOptions.Topology to "public" or "private" only.
- In Go, use the api.TopologyPublic / api.TopologyPrivate constants.
- Ensure the --topology flag value is validated before NewCluster is invoked.
Example fix
// before
opt := &NewClusterOptions{Topology: "public,private"}
// after
opt := &NewClusterOptions{Topology: api.TopologyPrivate} Defensive patterns
Strategy: type-guard
Validate before calling
if opt.Topology != api.TopologyPublic && opt.Topology != api.TopologyPrivate { return fmt.Errorf("topology must be public or private") } Type guard
func isValidTopology(t string) bool { return t == api.TopologyPublic || t == api.TopologyPrivate } Try / catch
if err := NewCluster(ctx, cloud, opt); err != nil && strings.Contains(err.Error(), "unknown topology type") { /* fix NewClusterOptions.Topology to a constant and retry */ } Prevention
- Always assign topology via api.Topology* constants, not raw strings
- Validate opt.Topology before calling NewCluster programmatically
- Reuse the same validation as setupTopology in test fixtures
When it happens
Trigger: NewClusterOptions.Topology set to a value other than api.TopologyPublic/api.TopologyPrivate while API access configuration requires topology-specific handling — normally only reachable when constructing options programmatically (Topology field set directly) or when earlier validation is bypassed.
Common situations: Go code/tests building NewClusterOptions with an arbitrary Topology string; scripts mutated between validation and use; refactors that removed the setupTopology validation path.
Understand the failure class
Background: "unknown output mode", "invalid value for flag", "expects true/false": fixing invalid flag value errors in CLI tools — this error's family across 24 libraries.
Related errors
- error describing Network: %v
- subnet %s not found in network %s
- cannot determine control-plane zones
- bastion supports --topology='private' only
- invalid topology %s
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/6e75c3baed128fd0.
Report an issue: GitHub.