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

  1. Ensure each ElasticIP task in the spec has a unique PublicIP; use the allocation ID (eipalloc-*) instead of public IP for unambiguous lookup
  2. Check for duplicate ElasticIP task definitions in `kops get cluster -oyaml`
  3. Verify the IAM credentials resolve to the intended single account (aws sts get-caller-identity)
  4. 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

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


AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05). Data as JSON: /api/errors/1bfbdce91ef886d2. Report an issue: GitHub.