{"record":{"id":"a460fbbd74163a02","repo":"hashicorp/terraform","slug":"lease-does-does-not-have-q-label","errorCode":null,"errorMessage":"Lease does does not have %q label","messagePattern":"Lease does does not have %q label","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/backend/remote-state/kubernetes/client.go","lineNumber":399,"sourceCode":"\tif !ok || v != \"true\" {\n\t\treturn fmt.Errorf(\"Secret does does not have %q label\", tfstateKey)\n\t}\n\n\tdelProp := metav1.DeletePropagationBackground\n\tdelOps := metav1.DeleteOptions{PropagationPolicy: &delProp}\n\treturn c.kubernetesSecretClient.Delete(context.Background(), name, delOps)\n}\n\nfunc (c *RemoteClient) deleteLease(name string) error {\n\tsecret, err := c.getLease(name)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tlabels := secret.GetLabels()\n\tv, ok := labels[tfstateKey]\n\tif !ok || v != \"true\" {\n\t\treturn fmt.Errorf(\"Lease does does not have %q label\", tfstateKey)\n\t}\n\n\tdelProp := metav1.DeletePropagationBackground\n\tdelOps := metav1.DeleteOptions{PropagationPolicy: &delProp}\n\treturn c.kubernetesLeaseClient.Delete(context.Background(), name, delOps)\n}\n\nfunc (c *RemoteClient) createSecretName(idx int) (string, error) {\n\tsecretName := strings.Join([]string{tfstateKey, c.workspace, c.nameSuffix}, \"-\")\n\n\tif idx > 0 {\n\t\tsecretName = fmt.Sprintf(\"%s-part-%d\", secretName, idx)\n\t}\n\n\terrs := validation.IsDNS1123Subdomain(secretName)\n\tif len(errs) > 0 {\n\t\tk8sInfo := `\nThis is a requirement for Kubernetes secret names. ","sourceCodeStart":381,"sourceCodeEnd":417,"githubUrl":"https://github.com/hashicorp/terraform/blob/c9def3e214014c1188faabfc4a5bde5095139765/internal/backend/remote-state/kubernetes/client.go#L381-L417","documentation":"deleteLease() refuses to delete a Lease that lacks the `tfstate=true` ownership label, mirroring the Secret guard. It GETs the lease, checks labels[tfstateKey]; if missing or not 'true' it aborts with this error (note the duplicated 'does does' wording). This protects against deleting Leases not owned by the backend.","triggerScenarios":"Delete() calling deleteLease(name) at client.go:390-405 against a Lease that exists but has no `tfstate=true` label - e.g. a lease of the same name created by another controller or an older backend version.","commonSituations":"A colliding Lease created by another application (Leases are shared objects in coordination.k8s.io); a lease left by an older Terraform that did not label its locks; manual lease creation with the computed lock name.","solutions":["Verify the Lease is actually a Terraform lock before touching it; if it is a leftover state lock, add the `tfstate=true` label or delete it manually with kubectl.","If the Lease belongs to another system, change secret_suffix/namespace so names no longer collide.","Re-run the deletion once the colliding/mislabeled Lease is resolved."],"exampleFix":"# before - leftover untagged lease blocks state cleanup\nterraform workspace delete myapp   # error: Lease does not have tfstate label\n\n# after - tag the legitimate lock lease (or delete it if stale)\nkubectl label lease lock-tfstate-default-myapp tfstate=true -n default\nterraform workspace delete myapp","handlingStrategy":"validation","validationCode":"// Verify the lease carries the ownership label before deletion\nlease, err := c.kubernetesLeaseClient.Get(ctx, name, metav1.GetOptions{})\nif err != nil { return err }\nif v, ok := lease.GetLabels()[\"tfstate\"]; !ok || v != \"true\" {\n    // not a backend-owned lease; skip\n    return nil\n}\nreturn c.kubernetesLeaseClient.Delete(ctx, name, metav1.DeleteOptions{})","typeGuard":"func isBackendOwnedLease(l *coordinationv1.Lease) bool {\n    v, ok := l.GetLabels()[\"tfstate\"]\n    return ok && v == \"true\"\n}","tryCatchPattern":null,"preventionTips":["Avoid reusing the lock-tfstate-<ws>-<suffix> name for non-Terraform leases.","Clean up stale lock leases during backend migrations.","Keep secret_suffix stable so lease names do not collide across reinstalls."],"tags":["kubernetes","remote-state","labels","lease","terraform-backend"],"analyzedSha":"c9def3e214014c1188faabfc4a5bde5095139765","analyzedAt":"2026-08-07T15:39:49.278Z","schemaVersion":2},"datasetVersion":"2026-08-07T20:17:04.800Z"}