{"record":{"id":"e0140f2385932d93","repo":"kubernetes/kops","slug":"projectid-does-not-match-expected-got-q-want-q","errorCode":null,"errorMessage":"projectID does not match expected: got %q, want %q","messagePattern":"projectID does not match expected: got %q, want %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/gce/tpm/gcetpmverifier/tpmverifier.go","lineNumber":126,"sourceCode":"\trequestHash := sha256.Sum256(body)\n\tif !bytes.Equal(requestHash[:], tokenData.RequestHash) {\n\t\treturn nil, fmt.Errorf(\"incorrect RequestHash\")\n\t}\n\n\t// Some basic validation to avoid requesting invalid instances.\n\tif tokenData.GCPProjectID == \"\" {\n\t\treturn nil, fmt.Errorf(\"gcpProjectID is required\")\n\t}\n\tif tokenData.Zone == \"\" {\n\t\treturn nil, fmt.Errorf(\"zone is required\")\n\t}\n\tif tokenData.Instance == \"\" {\n\t\treturn nil, fmt.Errorf(\"instance is required\")\n\t}\n\n\t// Verify node is in our cluster\n\tif tokenData.GCPProjectID != v.opt.ProjectID {\n\t\treturn nil, fmt.Errorf(\"projectID does not match expected: got %q, want %q\", tokenData.GCPProjectID, v.opt.ProjectID)\n\t}\n\n\tinstance, err := v.computeClient.Instances.Get(tokenData.GCPProjectID, tokenData.Zone, tokenData.Instance).Context(ctx).Do()\n\tif err != nil {\n\t\tif isNotFound(err) {\n\t\t\treturn nil, fmt.Errorf(\"unable to find instance in compute API: %w\", err)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"error fetching instance from compute API: %w\", err)\n\t}\n\n\tif !strings.HasPrefix(lastComponent(instance.Zone), v.opt.Region+\"-\") {\n\t\treturn nil, fmt.Errorf(\"instance was in zone %q, expected region %q\", instance.Zone, v.opt.Region)\n\t}\n\n\tclusterName := \"\"\n\tinstanceGroupName := \"\"\n\tfor _, item := range instance.Metadata.Items {\n\t\tswitch item.Key {","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/gce/tpm/gcetpmverifier/tpmverifier.go#L108-L144","documentation":"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.","triggerScenarios":"tokenData.GCPProjectID (from the signed token) differs from v.opt.ProjectID in the verifier's options.","commonSituations":"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.","solutions":["Correct v.opt.ProjectID (verifier configuration) to the project the nodes actually run in.","Fix the node/cluster configuration so instances are created in the expected project.","If the cluster intentionally moved projects, update the verifier's project and restart it."],"exampleFix":"// before\nv.opt.ProjectID = \"old-project\"\n// after\nv.opt.ProjectID = \"my-cluster-project\"","handlingStrategy":"validation","validationCode":"if tokenData.GCPProjectID != expectedProjectID {\n\treturn fmt.Errorf(\"token from project %q but verifier serves %q\", tokenData.GCPProjectID, expectedProjectID)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Double-check the verifier's ProjectID option at deploy time","Keep cluster project and verifier config in the same source of truth","Use one verifier per project in multi-project setups"],"tags":["gcp","tpm","configuration","authorization"],"backgroundTag":"project-id-mismatch","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}