{"record":{"id":"d9903fa66b46c9df","repo":"hashicorp/terraform","slug":"secret-does-does-not-have-q-label","errorCode":null,"errorMessage":"Secret does does not have %q label","messagePattern":"Secret does does not have %q label","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/backend/remote-state/kubernetes/client.go","lineNumber":382,"sourceCode":"\nfunc (c *RemoteClient) getSecret(name string) (*unstructured.Unstructured, error) {\n\treturn c.kubernetesSecretClient.Get(context.Background(), name, metav1.GetOptions{})\n}\n\nfunc (c *RemoteClient) getLease(name string) (*coordinationv1.Lease, error) {\n\treturn c.kubernetesLeaseClient.Get(context.Background(), name, metav1.GetOptions{})\n}\n\nfunc (c *RemoteClient) deleteSecret(name string) error {\n\tsecret, err := c.getSecret(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(\"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}","sourceCodeStart":364,"sourceCodeEnd":400,"githubUrl":"https://github.com/hashicorp/terraform/blob/d32a084675427f5ac3f7d2868578ef8b2c1dc525/internal/backend/remote-state/kubernetes/client.go#L364-L400","documentation":"Returned by deleteSecret when the targeted Secret lacks the tfstateKey label (value 'true') that the backend uses to mark managed Secrets (client.go:379-383). This is a safety guard preventing deletion of Secrets the backend did not create. Note: the message contains a typo ('does does') which is a known cosmetic bug in the source.","triggerScenarios":"deleteSecret is called on a Secret that was created manually or by another tool, or whose tfstateKey label was removed/never set. The label check (!ok || v != \"true\") fails.","commonSituations":"Manual relabeling or label-stripping by a mutation webhook; a Secret name collision with an unrelated Secret; the backend's label was overwritten by a kustomize/overlay; migrating label schemes.","solutions":["Confirm the Secret is actually a Terraform state Secret before acting; if so, re-add the tfstateKey=true label via kubectl label.","If the Secret is unrelated, do not delete it — investigate the naming collision.","Check for admission webhooks/mutation controllers that strip labels and exclude tfstate Secrets.","Report/ignore the 'does does' duplicate wording; it is cosmetic."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Before deleting, confirm the Secret is backend-managed:\n// sec, _ := getSecret(name)\n// if sec.GetLabels()[tfstateKey] != \"true\" { /* not managed; refuse to delete */ }","typeGuard":null,"tryCatchPattern":"// if err := client.deleteSecret(name); err != nil {\n//   if strings.Contains(err.Error(), \"Secret does does not have\") {\n//     // label missing; re-label if it is genuinely a state Secret, else investigate\n//   }\n// }","preventionTips":["Do not strip the tfstateKey=true label from backend-managed Secrets.","Exclude tfstate Secrets from label-mutating admission webhooks.","Avoid Secret name collisions with non-state Secrets."],"tags":["kubernetes-backend","secret","label","delete","guard"],"backgroundTag":null,"analyzedSha":"d32a084675427f5ac3f7d2868578ef8b2c1dc525","analyzedAt":"2026-08-11T18:43:52.779Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}