kubernetes/kops · error

providerID %q did not match our project %q

Error message

providerID %q did not match our project %q

What it means

The nodeIdentifier is bound to a specific GCE project (i.project). If the providerID's project component differs from the configured project, the identifier refuses to proceed — it assumes the instance is not part of this cluster's project and would not be authorized or meaningful to look up.

Source

Thrown at pkg/nodeidentity/gce/identify.go:115

	providerID := node.Spec.ProviderID
	if providerID == "" {
		return nil, fmt.Errorf("providerID was not set for node %s", node.Name)
	}
	if !strings.HasPrefix(providerID, "gce://") {
		return nil, fmt.Errorf("providerID %q not recognized for node %s", providerID, node.Name)
	}

	tokens := strings.Split(strings.TrimPrefix(providerID, "gce://"), "/")
	if len(tokens) != 3 {
		return nil, fmt.Errorf("providerID %q not recognized for node %s", providerID, node.Name)
	}

	project := tokens[0]
	zone := tokens[1]
	instanceName := tokens[2]

	if project != i.project {
		return nil, fmt.Errorf("providerID %q did not match our project %q", providerID, i.project)
	}

	instance, err := i.getInstance(zone, instanceName)
	if err != nil {
		return nil, err
	}

	instanceStatus := instance.Status
	if instanceStatus != "RUNNING" {
		return nil, fmt.Errorf("found instance %q, but status is %q", instanceName, instanceStatus)
	}

	capgRole := instance.Labels[LabelKeyCAPIRoleName]

	var capiMachine *clusterapi.Machine

	if i.capiManager != nil && capgRole != "" {
		providerID := "gce://" + project + "/" + zone + "/" + instanceName

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Run the node-identity controller with credentials/config for the project that actually hosts the nodes (set the project in cloud config or use credentials of that project's service account).
  2. Verify with `gcloud config get-value project` / the controller's startup config that i.project matches the cluster's node project.
  3. If nodes genuinely belong to another project, this node is out of scope — exclude it or run a separate identifier per project.
  4. Patch stale providerIDs pointing at old projects after cluster migration.

Example fix

// before (controller configured for proj-a, node in proj-b)
providerID = "gce://proj-b/us-central1-a/node-1"
// after — configure identifier with the node's project
i, _ := newNodeIdentifier(ctx, "proj-b", ...) // or fix node providerID to "gce://proj-a/..." if that's correct
Defensive patterns

Strategy: validation

Validate before calling

tokens := strings.Split(strings.TrimPrefix(node.Spec.ProviderID, "gce://"), "/")
if len(tokens) == 3 && tokens[0] != configuredProject {
    return fmt.Errorf("node %s belongs to project %s, controller configured for %s", node.Name, tokens[0], configuredProject)
}

Type guard

func providerIDMatchesProject(node *corev1.Node, project string) bool {
    t := strings.Split(strings.TrimPrefix(node.Spec.ProviderID, "gce://"), "/")
    return len(t) == 3 && t[0] == project
}

Try / catch

info, err := identifier.IdentifyNode(ctx, node)
if err != nil && strings.Contains(err.Error(), "did not match our project") {
    // out-of-scope node: skip rather than error
    return skipNode(node)
}

Prevention

When it happens

Trigger: Calling IdentifyNode with a node whose providerID is gce://other-project/zone/instance while the nodeIdentifier was constructed with project "my-project" (via its GCE credentials / cloud config).

Common situations: Shared VPC or multi-project deployments where nodes live in service projects but the controller runs with host-project credentials; copy-pasted node fixtures from another cluster; using default credentials from the wrong project; moved/re-created clusters reusing old node data.

Related errors


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