kubernetes/kops · error

providerID %q not recognized

Error message

providerID %q not recognized

What it means

getVMNameFromProviderID parses the providerID after trimming "azure://". This guard re-checks the scheme before parsing; a providerID without the "azure://" prefix returns this error. It is a defensive duplicate of the check in IdentifyNode and can also fire from other direct callers.

Source

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

	if i.cacheEnabled {
		err = i.cache.Add(info)
		if err != nil {
			klog.Warningf("Failed to add node identity info to cache: %v", err)
		}
	}

	return info, nil
}

// stringKeyFunc is a string as cache key function
func stringKeyFunc(obj interface{}) (string, error) {
	key := obj.(*nodeidentity.Info).InstanceID
	return key, nil
}

func getVMNameFromProviderID(providerID string) (string, error) {
	if !strings.HasPrefix(providerID, "azure://") {
		return "", fmt.Errorf("providerID %q not recognized", providerID)
	}

	res, err := arm.ParseResourceID(strings.TrimPrefix(providerID, "azure://"))
	if err != nil {
		return "", fmt.Errorf("error parsing providerID: %v", err)
	}

	switch res.ResourceType.String() {
	case "Microsoft.Compute/virtualMachines":
		return res.Name, nil
	case "Microsoft.Compute/virtualMachineScaleSets/virtualMachines":
		return res.Parent.Name + "_" + res.Name, nil
	default:
		return "", fmt.Errorf("unsupported resource type %q for providerID %q", res.ResourceType, providerID)
	}
}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Prefix the ID with "azure://" before calling, or trim the legacy "azure:///" form and re-add the expected scheme.
  2. Confirm the source of the providerID (kubectl get node) and that the Azure CCM version emits the current scheme.
  3. If invoking from custom code, normalize: if !strings.HasPrefix(id, "azure://") { id = "azure://" + strings.TrimPrefix(id, "azure:///") }.

Example fix

// before
name, err := getVMNameFromProviderID(node.Spec.ProviderID)

// after
pid := node.Spec.ProviderID
if !strings.HasPrefix(pid, "azure://") {
    pid = "azure://" + strings.TrimLeft(pid, "/")
}
name, err := getVMNameFromProviderID(pid)
Defensive patterns

Strategy: validation

Validate before calling

func isAzureProviderID(id string) bool {
    return strings.HasPrefix(id, "azure://")
}
if !isAzureProviderID(node.Spec.ProviderID) {
    return fmt.Errorf("cannot parse providerID %q", node.Spec.ProviderID)
}

Type guard

func isAzureProviderID(id string) bool {
    return strings.HasPrefix(id, "azure://")
}

Try / catch

name, err := getVMNameFromProviderID(pid)
if err != nil && strings.Contains(err.Error(), "not recognized") {
    return fmt.Errorf("normalize providerID %q to azure:// scheme first", pid)
}

Prevention

When it happens

Trigger: Calling getVMNameFromProviderID directly (or via the anonymous caller) with strings like "gce://project/zone/instance", "azure:///subscriptions/..." (double slash still fails HasPrefix? no—this fires only when prefix absent, e.g. bare resource ID "/subscriptions/.../virtualMachines/vm"), or empty string after stripping.

Common situations: Custom tooling that passes the resource ID without the scheme; providerIDs written by older or third-party controllers using a different scheme; unit tests or scripts calling the helper with raw ARM IDs.

Related errors


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