{"record":{"id":"b3c5f09bc009cf4a","repo":"kubernetes/kops","slug":"cannot-apply-changes-to-healthcheck-v","errorCode":null,"errorMessage":"cannot apply changes to healthcheck: %v","messagePattern":"cannot apply changes to healthcheck: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/gcetasks/healthcheck.go","lineNumber":159,"sourceCode":"\t\thc.Type = \"TCP\"\n\t\thc.TcpHealthCheck = &compute.TCPHealthCheck{\n\t\t\tPort: e.Port,\n\t\t}\n\t}\n\n\tif a == nil {\n\t\tklog.V(2).Infof(\"Creating HealthCheck %q\", hc.Name)\n\n\t\top, err := cloud.Compute().RegionHealthChecks().Insert(cloud.Project(), cloud.Region(), hc)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error creating healthcheck: %v\", err)\n\t\t}\n\n\t\tif err := cloud.WaitForOp(op); err != nil {\n\t\t\treturn fmt.Errorf(\"error waiting for healthcheck: %v\", err)\n\t\t}\n\t} else {\n\t\treturn fmt.Errorf(\"cannot apply changes to healthcheck: %v\", changes)\n\t}\n\n\treturn nil\n}\n\ntype terraformHealthCheckBlock struct {\n\tPort int64 `cty:\"port\"`\n}\n\ntype terraformHealthCheck struct {\n\tName           string                     `cty:\"name\"`\n\tTCPHealthCheck *terraformHealthCheckBlock `cty:\"tcp_health_check\"`\n\tSSLHealthCheck *terraformHealthCheckBlock `cty:\"ssl_health_check\"`\n}\n\nfunc (_ *HealthCheck) RenderTerraform(t *terraform.TerraformTarget, a, e, changes *HealthCheck) error {\n\ttf := &terraformHealthCheck{\n\t\tName: *e.Name,","sourceCodeStart":141,"sourceCodeEnd":177,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/gcetasks/healthcheck.go#L141-L177","documentation":"RenderGCE only supports creating a new health check (a == nil). If the task runs with an existing health check that has changes (actual != nil but changes non-empty), there is no update implementation, so it refuses with this error rather than silently ignoring drift.","triggerScenarios":"An existing regional HealthCheck in GCE differs from the desired spec (e.g. changed port, check interval, or protocol in the cluster spec) and the apply attempts to apply those changes.","commonSituations":"Editing the kops cluster spec to modify an existing health check's parameters; drift introduced out-of-band in the GCE console; upgrading kops where a task's default health check fields changed.","solutions":["Delete the existing health check (or the resource that owns it, e.g. the backend service/target pool) and re-run apply so it is recreated with the new spec","Revert the cluster spec change so desired matches the existing health check","Implement/handle the update path (Patch/Update call) in the task if you own the code"],"exampleFix":"null","handlingStrategy":"fallback","validationCode":"// detect drift before applying\nactual, err := cloud.Compute().RegionHealthChecks().Get(cloud.Project(), cloud.Region(), *e.Name)\nif err == nil && differs(actual, desired) { /* recreate or revert spec */ }","typeGuard":null,"tryCatchPattern":"if err != nil && strings.HasPrefix(err.Error(), \"cannot apply changes to healthcheck\") {\n\t// fallback: delete the health check and re-apply to recreate it\n}","preventionTips":["Do not mutate an existing GCE health check's fields via this task; recreate it instead","Avoid out-of-band edits in the GCE console to kops-managed health checks","Review kops upgrade notes for changed health check defaults before upgrading","Keep desired spec stable once the cluster is provisioned"],"tags":["gce","health-check","update-unsupported","drift"],"backgroundTag":"update-not-supported","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T07:17:12.445Z"}