kubernetes/kops · error

providerID %q not recognized for node %q

Error message

providerID %q not recognized for node %q

What it means

IdentifyNode maps a Kubernetes Node object to cloud identity info by parsing its Spec.ProviderID. If the providerID is present but does not start with the "azure://" scheme, kOps cannot treat it as an Azure resource and aborts identification. This indicates the node is running on a different cloud, the Cloud Provider Azure controller hasn't stamped a providerID yet, or the node was created with an unexpected providerID format.

Source

Thrown at pkg/nodeidentity/azure/identify.go:77

	if err != nil {
		return nil, err
	}

	return &nodeIdentifier{
		azureClient:  client,
		cache:        expirationcache.NewTTLStore(stringKeyFunc, cacheTTL),
		cacheEnabled: cacheNodeidentityInfo,
	}, nil
}

// IdentifyNode queries Azure for the node identity information.
func (i *nodeIdentifier) IdentifyNode(ctx context.Context, node *corev1.Node) (*nodeidentity.Info, error) {
	providerID := node.Spec.ProviderID
	if providerID == "" {
		return nil, fmt.Errorf("providerID not set for node %q", node.Name)
	}
	if !strings.HasPrefix(providerID, "azure://") {
		return nil, fmt.Errorf("providerID %q not recognized for node %q", providerID, node.Name)
	}

	vmName, err := getVMNameFromProviderID(providerID)
	if err != nil {
		return nil, err
	}

	// If caching is enabled, try pulling nodeidentity.Info from the cache before doing an API call.
	if i.cacheEnabled {
		obj, exists, err := i.cache.GetByKey(vmName)
		if err != nil {
			klog.Warningf("Nodeidentity info cache lookup failure: %v", err)
		}
		if exists {
			return obj.(*nodeidentity.Info), nil
		}
	}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Verify the Node's spec.providerID starts with "azure://" (kubectl get node <name> -o jsonpath='{.spec.providerID}').
  2. Ensure kubelet and cloud-controller-manager are configured with --cloud-provider=azure so they stamp azure-formatted providerIDs.
  3. Check for double-slash legacy format ("azure:///...") and update to the current CCM version or normalize the providerID before calling IdentifyNode.
  4. If the node genuinely belongs to another cloud, route it to the matching nodeidentity package (aws/gce/do) instead of the azure one.

Example fix

// before: routing every node through azure identifier
info, err := azureIdentifier.IdentifyNode(ctx, node)

// after: guard on prefix first
if !strings.HasPrefix(node.Spec.ProviderID, "azure://") {
    return nil, fmt.Errorf("skipping non-azure node %q", node.Name)
}
info, err := azureIdentifier.IdentifyNode(ctx, node)
Defensive patterns

Strategy: validation

Validate before calling

if node.Spec.ProviderID == "" || !strings.HasPrefix(node.Spec.ProviderID, "azure://") {
    return fmt.Errorf("node %q has non-azure providerID %q", node.Name, node.Spec.ProviderID)
}

Try / catch

info, err := identifier.IdentifyNode(ctx, node)
if err != nil {
    if strings.Contains(err.Error(), "not recognized for node") {
        // skip non-azure node or route to correct cloud identifier
        return nil, err
    }
    return nil, err
}

Prevention

When it happens

Trigger: Calling IdentifyNode with a Node whose Spec.ProviderID is non-empty but lacks the "azure://" prefix, e.g. "aws:///us-east-1a/i-abc123" or a bare VM name. Typically occurs when the nodeidentifier is wired to a cluster whose nodes were provisioned by another cloud provider, or the azure providerID is in a legacy format.

Common situations: Running the kOps node-authorizer/azure nodeidentity code against nodes from a mixed or migrated cluster; kubelet's --cloud-provider not being azure so providerID is set by another component; copy-paste of cluster config from an AWS cluster; Azure providerID format changed between CCM versions (e.g. "azure:///subscriptions/..." vs "azure://...").

Related errors


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