kubernetes/kops · error
Unable to tag subnet %v
Error message
Unable to tag subnet %v
What it means
When tagging the associated subnet via t.AddAWSTags(*e.TagOnSubnet.ID, tags) fails, RenderAWS wraps the error as 'Unable to tag subnet %v'. The EIP itself was allocated successfully, but writing the AssociatedElasticIp tags onto the subnet failed, leaving reconciliation incomplete (and, per code comments, risking a leaked EIP).
Source
Thrown at upup/pkg/fi/cloudup/awstasks/elastic_ip.go:265
} else {
publicIp = a.PublicIP
eipId = a.ID
if err := t.AddAWSTags(*e.ID, e.Tags); err != nil {
return err
}
}
// Tag the associated subnet
if e.TagOnSubnet != nil {
if e.TagOnSubnet.ID == nil {
return fmt.Errorf("Subnet ID not set")
}
tags := make(map[string]string)
tags["AssociatedElasticIp"] = *publicIp
tags["AssociatedElasticIpAllocationId"] = *eipId // Leaving this in for reference, even though we don't use it
err := t.AddAWSTags(*e.TagOnSubnet.ID, tags)
if err != nil {
return fmt.Errorf("Unable to tag subnet %v", err)
}
} else {
// TODO: Figure out what we can do. We're sort of stuck between wanting to have one code-path with
// terraform, and having a bigger "window of loss" here before we create the NATGateway
klog.V(2).Infof("ElasticIP %q not tagged on subnet; risk of leaking", fi.ValueOf(publicIp))
}
return nil
}
type terraformElasticIP struct {
Domain *string `cty:"domain"`
Tags map[string]string `cty:"tags"`
}
func (_ *ElasticIP) RenderTerraform(t *terraform.TerraformTarget, a, e, changes *ElasticIP) error {
if fi.ValueOf(e.Shared) {
if e.ID == nil {View on GitHub (pinned to 4c8573c808)
Solutions
- Grant ec2:CreateTags in the kops IAM policy and re-run kops update cluster
- Verify the subnet still exists: aws ec2 describe-subnets --subnet-ids <id>
- Retry after throttling; add jitter/backoff in CI
- Consider dropping TagOnSubnet (deprecated) and relying on NAT gateway association discovery
Example fix
// before: denied
{"Effect":"Deny"} // no ec2:CreateTags
// after
{"Effect":"Allow","Action":["ec2:CreateTags"],"Resource":"*"} Defensive patterns
Strategy: try-catch
Validate before calling
// pre-check subnet exists and credentials can tag
_, err := ec2Client.DescribeSubnets(ctx, &ec2.DescribeSubnetsInput{SubnetIds: []string{subnetID}})
if err != nil { return fmt.Errorf("subnet %s unavailable: %w", subnetID, err) } Try / catch
err := runKopsUpdate(ctx)
if err != nil && strings.Contains(err.Error(), "Unable to tag subnet") {
// check ec2:CreateTags IAM permission and subnet existence before retry
} Prevention
- Grant ec2:CreateTags for subnet resources in the kops IAM policy
- Avoid deleting subnets concurrently with updates
- Keep tag values short enough for AWS limits
- Migrate away from deprecated TagOnSubnet
When it happens
Trigger: ec2.CreateTags on the subnet fails: IAM policy missing ec2:CreateTags, subnet deleted concurrently, invalid subnet ID, throttling, or tag-value validation failure for AssociatedElasticIp/AssociatedElasticIpAllocationId.
Common situations: Least-privilege IAM policies missing ec2:CreateTags on subnet resources; race with concurrent cluster deletion; very long tag values rejected by AWS.
Related errors
- error adding AWS Tags to EBS Volume: %v
- error listing subnets in VPC %q: %v
- provider ID cannot be empty
- error listing subnets: %v
- error listing RouteTables: %v
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/0aa5067b7112cef6.
Report an issue: GitHub.