kubernetes/kops · error
unable to tag subnet %v
Error message
unable to tag subnet %v
What it means
Right after validating the subnet, RenderAWS tags the subnet with AssociatedNatgateway=<ngw-id> via t.AddAWSTags. If that AWS ec2 CreateTags call fails, the error is wrapped as "unable to tag subnet %v".
Source
Thrown at upup/pkg/fi/cloudup/awstasks/natgateway.go:346
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")
}
klog.V(2).Infof("tagging route table %s to track shared NGW", fi.ValueOf(e.AssociatedRouteTable.ID))
err = t.AddAWSTags(fi.ValueOf(e.AssociatedRouteTable.ID), tags)
if err != nil {
return fmt.Errorf("unable to tag route table %v", err)
}
}
View on GitHub (pinned to 4c8573c808)
Solutions
- Read the wrapped %v cause: if it is UnauthorizedOperation, grant ec2:CreateTags on the subnet in the kops IAM policy
- If InvalidSubnetID.NotFound, re-run kops update — the subnet no longer exists and must be recreated
- Retry the apply on transient AWS errors (throttling); consider reducing concurrent API calls
- Verify the subnet ID from the spec exists in the target region/account
Example fix
// before (IAM policy for kops controllers missing subnet tag permission)
{ "Effect": "Deny", ... subnet resources }
// after
allow ec2:CreateTags on arn:aws:ec2:*:*:subnet/* for the kops principal Defensive patterns
Strategy: retry
Validate before calling
_, err := cloud.EC2().DescribeSubnets(&ec2.DescribeSubnetsInput{SubnetIds: []string{*subnetID}})
if err != nil { return fmt.Errorf("subnet %s not taggable/visible: %w", *subnetID, err) } Try / catch
err := apply()
var awsErr smithy.APIError
if errors.As(err, &awsErr) && awsErr.ErrorCode() == "ThrottlingException" {
time.Sleep(backoff); retry()
} Prevention
- Ensure IAM policy includes ec2:CreateTags on subnet ARNs
- Retry applies on transient AWS errors
- Confirm the subnet still exists before applying
When it happens
Trigger: AddAWSTags(*e.Subnet.ID, tags) returns an error during RenderAWS — e.g. AWS API error (throttling, InvalidSubnetID.NotFound, permission denied on ec2:CreateTags for the subnet).
Common situations: IAM policy lacking ec2:CreateTags on shared subnet ARNs; subnet deleted out-of-band between discovery and tagging; transient AWS throttling during apply.
Related errors
- unable to tag route table %v
- DIGITALOCEAN_ACCESS_TOKEN is required
- writing keyset: %v
- checking if bucket was public: %w
- error describing RouteTables: %v
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/62ba40881ee624a3.
Report an issue: GitHub.