kubernetes/kops · error

found multiple machines with providerID %q

Error message

found multiple machines with providerID %q

What it means

After filtering Machine objects by matching spec.providerID, FindMachineByProviderID expects at most one match. If more than one Machine in the management cluster reports the same providerID, it returns this error rather than guessing. Duplicates indicate a serious CAPI state problem: leftover Machines from a failed rollout or cloned Machine objects sharing a backing instance.

Source

Thrown at pkg/nodeidentity/clusterapi/capimanager/manager.go:67

		Group:   "cluster.x-k8s.io",
		Kind:    "Machine",
		Version: "v1beta1",
	})
	if err := m.kubeClient.List(ctx, &machines); err != nil {
		return nil, fmt.Errorf("error listing machines: %w", err)
	}
	var matches []*unstructured.Unstructured
	for i := range machines.Items {
		machine := &machines.Items[i]
		machineSpecProviderID, _, _ := unstructured.NestedString(machine.Object, "spec", "providerID")
		if machineSpecProviderID != providerID {
			continue
		}
		matches = append(matches, machine)
	}
	if len(matches) > 0 {
		if len(matches) > 1 {
			return nil, fmt.Errorf("found multiple machines with providerID %q", providerID)
		}
		machine := matches[0]
		machine = machine.DeepCopy()
		return clusterapi.NewMachine(machine), nil
	}

	return nil, nil
}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. List machines and inspect duplicates: kubectl get machines -o jsonpath range over spec.providerID; identify the stale one.
  2. Delete the orphaned/terminating duplicate Machine (ensure it is not backed by a live node).
  3. Check the owning MachineDeployment/KubeadmControlPlane for stuck rollouts and fix the revision so old Machines are reaped.
  4. Prevent recurrence by ensuring providerIDs are unique per instance and avoid restoring duplicate Machine manifests.

Example fix

// before: stale duplicate
kubectl get machine worker-abc worker-abc-old   # both spec.providerID azure://...same

// after: remove the orphan
kubectl delete machine worker-abc-old
Defensive patterns

Strategy: validation

Validate before calling

var machines unstructured.UnstructuredList
_ = kubeClient.List(ctx, &machines)
counts := map[string]int{}
for i := range machines.Items {
    pid, _, _ := unstructured.NestedString(machines.Items[i].Object, "spec", "providerID")
    counts[pid]++
}
for pid, n := range counts {
    if n > 1 {
        return fmt.Errorf("providerID %q claimed by %d machines; clean up duplicates", pid, n)
    }
}

Try / catch

machine, err := mgr.FindMachineByProviderID(ctx, providerID)
if err != nil && strings.Contains(err.Error(), "found multiple machines") {
    return fmt.Errorf("inspect 'kubectl get machines' and delete the stale duplicate before retrying: %w", err)
}

Prevention

When it happens

Trigger: Two or more Machine objects whose spec.providerID equals the queried value — e.g. a Machine was deleted and recreated but the old object lingers in a terminating state, machines were copied across clusters/management clusters, or a rollout created a new Machine before the old one's providerID was cleared.

Common situations: Interrupted Cluster API rollout/upgrade leaving orphaned Machine resources; restoring Machine objects from backups into the same management cluster; manually creating a Machine with a providerID copied from an existing one; KCP/MachineDeployment reconciliation bugs.

Related errors


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