kubernetes/kops · error
found multiple ElasticIPs for: %v
Error message
found multiple ElasticIPs for: %v
What it means
find() requires DescribeAddresses to return exactly one address for the allocation ID or public-ip filter. If more than one address matches (e.g. the public-ip filter matches several addresses across accounts/regions is impossible, but can occur with permissive filters or duplicated state), it throws 'found multiple ElasticIPs for: %v' because kOps cannot unambiguously map AWS state onto the single task.
Source
Thrown at upup/pkg/fi/cloudup/awstasks/elastic_ip.go:144
if publicIP != nil || allocationID != nil {
request := &ec2.DescribeAddressesInput{}
if allocationID != nil {
request.AllocationIds = []string{fi.ValueOf(allocationID)}
} else if publicIP != nil {
request.Filters = []ec2types.Filter{awsup.NewEC2Filter("public-ip", *publicIP)}
}
response, err := cloud.EC2().DescribeAddresses(ctx, request)
if err != nil {
return nil, fmt.Errorf("error listing ElasticIPs: %v", err)
}
if response == nil || len(response.Addresses) == 0 {
return nil, fmt.Errorf("found no ElasticIPs for: %v", e)
}
if len(response.Addresses) != 1 {
return nil, fmt.Errorf("found multiple ElasticIPs for: %v", e)
}
a := response.Addresses[0]
actual := &ElasticIP{
ID: a.AllocationId,
PublicIP: a.PublicIp,
}
actual.TagOnSubnet = e.TagOnSubnet
actual.AssociatedNatGatewayRouteTable = e.AssociatedNatGatewayRouteTable
{
tags, err := cloud.EC2().DescribeTags(ctx, &ec2.DescribeTagsInput{
Filters: []ec2types.Filter{
{
Name: aws.String("resource-id"),
Values: []string{aws.ToString(a.AllocationId)},
},
},
})View on GitHub (pinned to 4c8573c808)
Solutions
- Ensure each ElasticIP task in the spec has a unique PublicIP; use the allocation ID (eipalloc-*) instead of public IP for unambiguous lookup
- Check for duplicate ElasticIP task definitions in `kops get cluster -oyaml`
- Verify the IAM credentials resolve to the intended single account (aws sts get-caller-identity)
- If an IPAM resource share is aggregating addresses, scope the lookup or use explicit AllocationIds
Example fix
// before: ambiguous lookup by public IP
PublicIP: fi.String("52.1.2.3")
// after: pin to exact allocation
ID: fi.String("eipalloc-0abc123def4567890") Defensive patterns
Strategy: type-guard
Validate before calling
func uniqueAddresses(addrs []ec2types.Address) bool { return len(addrs) <= 1 }
// call DescribeAddresses and assert uniqueness before reconciling Type guard
func singleMatch(rs []ec2types.Address) (*ec2types.Address, bool) {
if len(rs) != 1 { return nil, false }
return &rs[0], true
} Try / catch
if err != nil && strings.Contains(err.Error(), "found multiple ElasticIPs") {
// fall back to exact AllocationIds lookup instead of public-ip filter
} Prevention
- Prefer allocation ID over public IP in specs
- Ensure one AWS account/credential chain is in use (no Organizations aggregation surprises)
- Keep PublicIP values unique across tasks
- Audit specs for duplicate ElasticIP definitions
When it happens
Trigger: len(response.Addresses) > 1 after DescribeAddresses with a public-ip filter returning multiple matches — practically caused by duplicated spec entries with the same PublicIP, or by a filter that isn't unique (e.g. a public-ip value reused via VPC sharing / multiple accounts aggregated in a management role).
Common situations: Cross-account aggregated resource views via AWS Organizations and a shared management IAM role; copy-pasted identical PublicIP values across different cluster task definitions; resource share (IPAM pool) returning multiple matching addresses.
Related errors
- error describing addresses: %v
- error from DescribeAddresses: %v
- error deleting elastic ip %q: %v
- error finding AssociatedNatGatewayRouteTable: %v
- error listing ElasticIPs: %v
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/1bfbdce91ef886d2.
Report an issue: GitHub.