kubernetes/kops · error

found multiple instances with instance id: %s

Error message

found multiple instances with instance id: %s

What it means

During node bootstrap verification, kOps looks up the instance that made the STS GetCallerIdentity call via ec2.DescribeInstances with the instance ID extracted from the assumed-role ARN. AWS guarantees instance IDs are unique, so DescribeInstances returning more than one instance for a single ID is an invariant violation the verifier refuses to guess its way through. It throws this to avoid issuing certificates against the wrong machine.

Source

Thrown at pkg/bootstrap/awsbootstrap/verifier.go:305

		}
	}
	if !found {
		return nil, fmt.Errorf("arn %q does not contain acceptable node role", arn)
	}

	instanceID := resource[2]
	instances, err := a.ec2.DescribeInstances(ctx, &ec2.DescribeInstancesInput{
		InstanceIds: []string{instanceID},
	})
	if err != nil {
		return nil, fmt.Errorf("describing instance for arn %q", arn)
	}

	if len(instances.Reservations) <= 0 || len(instances.Reservations[0].Instances) <= 0 {
		return nil, fmt.Errorf("missing instance id: %s", instanceID)
	}
	if len(instances.Reservations[0].Instances) > 1 {
		return nil, fmt.Errorf("found multiple instances with instance id: %s", instanceID)
	}

	instance := instances.Reservations[0].Instances[0]

	addrs, err := GetInstanceCertificateNames(instances)
	if err != nil {
		return nil, err
	}

	var challengeEndpoints []string
	for _, nic := range instance.NetworkInterfaces {
		if ip := aws.ToString(nic.PrivateIpAddress); ip != "" {
			challengeEndpoints = append(challengeEndpoints, net.JoinHostPort(ip, strconv.Itoa(wellknownports.NodeupChallenge)))
		}
		for _, a := range nic.PrivateIpAddresses {
			if ip := aws.ToString(a.PrivateIpAddress); ip != "" {
				challengeEndpoints = append(challengeEndpoints, net.JoinHostPort(ip, strconv.Itoa(wellknownports.NodeupChallenge)))
			}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Retry the bootstrap token verification; a transient EC2 API anomaly usually resolves on a fresh DescribeInstances call.
  2. Check the AWS account/region for duplicate resources or an EC2 API proxy/interceptor that could duplicate reservation entries.
  3. If using a mocked EC2 endpoint (tests, LocalStack), fix the mock so one instance ID maps to exactly one instance.
  4. Check the kOps version for known issues and upgrade if the error persists on every bootstrap attempt.

Example fix

// For test stubs that triggered the error:
// before
return &ec2.DescribeInstancesOutput{Reservations: []types.Reservation{
  {Instances: []types.Instance{inst, inst}},
}}
// after
return &ec2.DescribeInstancesOutput{Reservations: []types.Reservation{
  {Instances: []types.Instance{inst}},
}}
Defensive patterns

Strategy: retry

Validate before calling

out, err := ec2Client.DescribeInstances(ctx, &ec2.DescribeInstancesInput{InstanceIds: []string{instanceID}})
if err != nil { return err }
n := 0
for _, r := range out.Reservations { n += len(r.Instances) }
if n == 0 { return fmt.Errorf("instance %s not found yet", instanceID) }
if n > 1 { return fmt.Errorf("ambiguous DescribeInstances response for %s", instanceID) }

Type guard

func exactlyOneInstance(out *ec2.DescribeInstancesOutput) (types.Instance, bool) {
  var inst []types.Instance
  for _, r := range out.Reservations { inst = append(inst, r.Instances...) }
  if len(inst) != 1 { return types.Instance{}, false }
  return inst[0], true
}

Try / catch

for attempt := 0; attempt < 3; attempt++ {
  result, err := verifier.VerifyToken(ctx, token)
  if err != nil && strings.Contains(err.Error(), "found multiple instances") {
    time.Sleep(backoff(attempt)); continue // transient EC2 API anomaly
  }
  return result, err
}

Prevention

When it happens

Trigger: verifyCallerIdentity (via verifyTokenV1/verifyTokenV2) calls ec2.DescribeInstances(InstanceIds=[instanceID]) and the response contains len(Reservations[0].Instances) > 1 — i.e. EC2 returned multiple instance entries for the single requested ID.

Common situations: Almost always an AWS API/SDK anomaly or a mocked/stubbed EC2 backend returning malformed reservations rather than a user misconfiguration; seen occasionally with regional STS endpoints paired with buggy EC2 responses, or in fake/ mocks used in tests where the DescribeInstances stub returns duplicate instances.

Related errors


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