kubernetes/kops · error

projectID does not match expected: got %q, want %q

Error message

projectID does not match expected: got %q, want %q

What it means

The verifier enforces that the token's GCPProjectID equals the project it was configured to serve (v.opt.ProjectID). This stops instances from other projects — even ones with valid tokens — from authenticating into this cluster.

Source

Thrown at upup/pkg/fi/cloudup/gce/tpm/gcetpmverifier/tpmverifier.go:126

	requestHash := sha256.Sum256(body)
	if !bytes.Equal(requestHash[:], tokenData.RequestHash) {
		return nil, fmt.Errorf("incorrect RequestHash")
	}

	// Some basic validation to avoid requesting invalid instances.
	if tokenData.GCPProjectID == "" {
		return nil, fmt.Errorf("gcpProjectID is required")
	}
	if tokenData.Zone == "" {
		return nil, fmt.Errorf("zone is required")
	}
	if tokenData.Instance == "" {
		return nil, fmt.Errorf("instance is required")
	}

	// Verify node is in our cluster
	if tokenData.GCPProjectID != v.opt.ProjectID {
		return nil, fmt.Errorf("projectID does not match expected: got %q, want %q", tokenData.GCPProjectID, v.opt.ProjectID)
	}

	instance, err := v.computeClient.Instances.Get(tokenData.GCPProjectID, tokenData.Zone, tokenData.Instance).Context(ctx).Do()
	if err != nil {
		if isNotFound(err) {
			return nil, fmt.Errorf("unable to find instance in compute API: %w", err)
		}
		return nil, fmt.Errorf("error fetching instance from compute API: %w", err)
	}

	if !strings.HasPrefix(lastComponent(instance.Zone), v.opt.Region+"-") {
		return nil, fmt.Errorf("instance was in zone %q, expected region %q", instance.Zone, v.opt.Region)
	}

	clusterName := ""
	instanceGroupName := ""
	for _, item := range instance.Metadata.Items {
		switch item.Key {

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Correct v.opt.ProjectID (verifier configuration) to the project the nodes actually run in.
  2. Fix the node/cluster configuration so instances are created in the expected project.
  3. If the cluster intentionally moved projects, update the verifier's project and restart it.

Example fix

// before
v.opt.ProjectID = "old-project"
// after
v.opt.ProjectID = "my-cluster-project"
Defensive patterns

Strategy: validation

Validate before calling

if tokenData.GCPProjectID != expectedProjectID {
	return fmt.Errorf("token from project %q but verifier serves %q", tokenData.GCPProjectID, expectedProjectID)
}

Prevention

When it happens

Trigger: tokenData.GCPProjectID (from the signed token) differs from v.opt.ProjectID in the verifier's options.

Common situations: Verifier deployed with the wrong --project / ProjectID option, cluster moved to a different GCP project without updating the verifier config, a multi-project setup sending nodes to the wrong verifier, or a typo in the project ID configuration.

Related errors


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