kubernetes/kops · error

error identifying node %q: %v

Error message

error identifying node %q: %v

What it means

The node controller failed to determine the cloud identity of a Node object. kops-controller calls r.identifier.IdentifyNode(ctx, node) to map a Kubernetes Node to cloud provider metadata (instance ID, labels, zones); any underlying failure is wrapped with the node name for context.

Source

Thrown at cmd/kops-controller/controllers/node_controller.go:90

// Reconcile is the main reconciler function that observes node changes.
func (r *NodeReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
	_ = r.log.WithValues("nodecontroller", req.NamespacedName)

	node := &corev1.Node{}
	if err := r.client.Get(ctx, req.NamespacedName, node); err != nil {
		klog.Warningf("unable to fetch node %s: %v", node.Name, err)
		if apierrors.IsNotFound(err) {
			// we'll ignore not-found errors, since they can't be fixed by an immediate
			// requeue (we'll need to wait for a new notification), and we can get them
			// on deleted requests.
			return ctrl.Result{}, nil
		}
		return ctrl.Result{}, err
	}

	info, err := r.identifier.IdentifyNode(ctx, node)
	if err != nil {
		return ctrl.Result{}, fmt.Errorf("error identifying node %q: %v", node.Name, err)
	}

	labels := info.Labels

	updateLabels := make(map[string]string)
	for k, v := range labels {
		actual, found := node.Labels[k]
		if !found || actual != v {
			updateLabels[k] = v
		}
	}

	deleteLabels := make(map[string]struct{})
	for k := range node.Labels {
		// If it is one of our managed labels, "prune" values we don't want to be there
		switch k {
		case nodelabels.RoleLabelAPIServer16, nodelabels.RoleLabelNode16, nodelabels.RoleLabelControlPlane20:
			if _, found := labels[k]; !found {

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Check the wrapped %v error for the root cause (usually an AWS/GCE API permission or throttling failure)
  2. Verify kops-controller IAM role has ec2:DescribeInstances (or GCE compute.instances.get) permissions
  3. Confirm the Node's spec.providerID is set and correctly formatted
  4. Verify network connectivity from the controller pod to the cloud metadata/API endpoints
  5. Restart the controller — reconciliation will retry the node

Example fix

// before: controller lacks permission, error like UnauthorizedOperation
// after: attach policy
{
  "Effect": "Allow",
  "Action": ["ec2:DescribeInstances"],
  "Resource": ["*"]
}
Defensive patterns

Strategy: retry

Validate before calling

if node.Spec.ProviderID == "" {
	// cannot identify yet; skip and requeue
}

Try / catch

info, err := r.identifier.IdentifyNode(ctx, node)
if err != nil {
	if kerrors.IsNotFound(err) { return ctrl.Result{}, nil }
	return ctrl.Result{RequeueAfter: time.Minute}, fmt.Errorf("error identifying node %q: %v", node.Name, err)
}

Prevention

When it happens

Trigger: IdentifyNode returns an error — e.g. the cloud metadata lookup fails (AWS EC2 DescribeInstances denied/failed), the instance ID cannot be resolved from the provider ID, or the cloud-specific identifier constructor config is wrong.

Common situations: IAM permissions missing for the controller's EC2/GCE API calls, node with malformed or empty spec.providerID, network egress blocked to the cloud API, or a node registered before the controller's identifier was properly initialized.

Related errors


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