kubernetes/kops · error
Subnet ID not set
Error message
Subnet ID not set
What it means
In RenderAWS for the NatGateway task, kOps tags the subnet associated with the NAT gateway using AddAWSTags. Before tagging it validates that e.Subnet is set and that its ID is populated. If the subnet exists as a task reference but its AWS ID is nil (not yet resolved), the render aborts with "Subnet ID not set".
Source
Thrown at upup/pkg/fi/cloudup/awstasks/natgateway.go:338
if err != nil {
return fmt.Errorf("Error creating Nat Gateway: %v", err)
}
e.ID = response.NatGateway.NatGatewayId
id = e.ID
} else {
id = a.ID
}
err := t.AddAWSTags(*e.ID, e.Tags)
if err != nil {
return fmt.Errorf("unable to tag NatGateway")
}
// Tag the associated subnet
if e.Subnet == nil {
return fmt.Errorf("Subnet not set")
} else if e.Subnet.ID == nil {
return fmt.Errorf("Subnet ID not set")
}
// TODO: AssociatedNatgateway tag is obsolete - we can get from the route table instead
tags := make(map[string]string)
tags["AssociatedNatgateway"] = *id
err = t.AddAWSTags(*e.Subnet.ID, tags)
if err != nil {
return fmt.Errorf("unable to tag subnet %v", err)
}
// If this is a shared NGW, we need to tag it
// The tag that implies "shared" is `AssociatedNatgateway`=> NGW-ID
// This is better than just a tag that's shared because this lets us create a whitelist of these NGWs
// without doing a bunch more work in `kutil/delete_cluster.go`
if fi.ValueOf(e.Shared) {
if e.AssociatedRouteTable == nil {
return fmt.Errorf("AssociatedRouteTable not provided")View on GitHub (pinned to 4c8573c808)
Solutions
- Ensure the Subnet task for this NAT gateway is included in the target and has a resolvable ID (not nil) before the NAT gateway render
- Check the cluster spec that the NAT gateway's Subnet field points at a defined, non-shared subnet with an ID
- Run kops update with the correct lifecycle so subnet tasks execute before the NAT gateway task
- If the subnet is shared, populate its ID explicitly in the spec
Example fix
// before (task graph omits the subnet the NGW references) NatGateway: Subnet: nil-referenced subnet // after nat.Subnet = fi.WrapSubnet(subnetTask) // subnetTask is a real awstasks.Subnet with a set ID and earlier lifecycle
Defensive patterns
Strategy: validation
Validate before calling
if nat.Subnet == nil || nat.Subnet.ID == nil {
return fmt.Errorf("nat gateway %s has no resolvable subnet ID; define/lifecycle the subnet task first", name)
} Type guard
func hasSubnetID(s *awstasks.Subnet) bool { return s != nil && s.ID != nil } Prevention
- Always define the Subnet task before the NatGateway task that references it
- Check `kops update --dry-run` output for unresolved subnet references
- Avoid hand-editing subnet IDs out of spec
When it happens
Trigger: RenderAWS runs during aws target apply when e.Subnet is non-nil but e.Subnet.ID == nil, typically because the subnet task was never provisioned/lifecycled before the NAT gateway, or the subnet reference came from a shared/imported spec without an ID.
Common situations: Cluster spec where a utility subnet references a subnet with an unknown ID; misordered task lifecycle (subnet deferred or omitted); hand-edited cluster spec or terraform import missing the subnet ID.
Related errors
- subnet %q had unknown type %q
- subnet %q had unknown type %q
- could not find public subnet in zone: %q
- found multiple public subnets in zone: %q
- error listing subnets: %v
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/0b7cbcb13331d5e1.
Report an issue: GitHub.