kubernetes/kops · error

found multiple VPCs for %q

Error message

found multiple VPCs for %q

What it means

Returned by FindVPC when DescribeVpcs filtered by a single VPC ID returns more than one VPC (aws_cloud.go:1680). A VPC ID should match exactly one VPC, so this indicates a violated invariant rather than a user-input problem per se.

Source

Thrown at upup/pkg/fi/cloudup/awsup/aws_cloud.go:1680

	return describeVPC(c, vpcID)
}

func describeVPC(c AWSCloud, vpcID string) (*ec2types.Vpc, error) {
	klog.V(2).Infof("Calling DescribeVPC for VPC %q", vpcID)
	ctx := context.TODO()
	request := &ec2.DescribeVpcsInput{
		VpcIds: []string{vpcID},
	}

	response, err := c.EC2().DescribeVpcs(ctx, request)
	if err != nil {
		return nil, fmt.Errorf("error listing VPCs: %v", err)
	}
	if response == nil || len(response.Vpcs) == 0 {
		return nil, nil
	}
	if len(response.Vpcs) != 1 {
		return nil, fmt.Errorf("found multiple VPCs for %q", vpcID)
	}

	vpc := response.Vpcs[0]
	return &vpc, nil
}

// ResolveImage finds an AMI image based on the given name.
// The name can be one of:
// `ami-...` in which case it is presumed to be an id
// owner/name in which case we find the image with the specified name, owned by owner
// name in which case we find the image with the specified name, with the current owner
func (c *awsCloudImplementation) ResolveImage(name string) (*ec2types.Image, error) {
	return resolveImage(context.TODO(), c.ssm, c.ec2, name)
}

func resolveSSMParameter(ctx context.Context, ssmClient awsinterfaces.SSMAPI, name string) (string, error) {
	klog.V(2).Infof("Resolving SSM parameter %q", name)
	request := &ssm.GetParameterInput{

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Verify the VPC ID is well-formed and unique via `aws ec2 describe-vpcs --vpc-ids <id>` against real AWS
  2. If using a custom EC2 endpoint (e.g. LocalStack), clear stale state or disable the custom endpoint
  3. Retry the operation; if it persists, report it — on real AWS a VPC ID is unique and this is an API-contract violation

Example fix

// before
export AWS_EC2_ENDPOINT=http://localhost:4566
// after
unset AWS_EC2_ENDPOINT  # use the real EC2 endpoint
Defensive patterns

Strategy: type-guard

Validate before calling

// Validate uniqueness client-side with the same filter kops uses
out, err := ec2Client.DescribeVpcs(ctx, &ec2.DescribeVpcsInput{VpcIds: []string{vpcID}})
if err == nil && len(out.Vpcs) > 1 { return fmt.Errorf("ambiguous VPC result for %s", vpcID) }

Type guard

func exactlyOneVPC(out *ec2.DescribeVpcsOutput) (*ec2types.Vpc, bool) {
	if out == nil || len(out.Vpcs) != 1 { return nil, false }
	return &out.Vpcs[0], true
}

Try / catch

vpc, err := cloud.FindVPC(ctx, vpcID)
if err != nil {
	if strings.Contains(err.Error(), "found multiple VPCs") {
		// treat as endpoint anomaly: drop custom endpoints / retry once
	}
	return err
}

Prevention

When it happens

Trigger: The EC2 DescribeVpcs call with VpcIds=[vpcID] returns len(response.Vpcs) != 1 after the empty check — essentially only possible with a duplicate-ID response or a client/proxy anomaly.

Common situations: Rare in practice; seen with misbehaving EC2-compatible endpoints (custom API endpoints, LocalStack, Outposts-like setups) or stale mocked responses where the ID filter is not honored.

Related errors


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