{"record":{"id":"8281b15772d42721","repo":"hashicorp/terraform","slug":"failed-to-delete-tag-s-s-s","errorCode":null,"errorMessage":"failed to delete tag: %s -> %s: %s","messagePattern":"failed to delete tag: (.+?) -> (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/backend/remote-state/cos/client.go","lineNumber":446,"sourceCode":"\t_, err := c.tagClient.CreateTag(request)\n\tlog.Printf(\"[DEBUG] create tag %s:%s: error: %v\", key, value, err)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to create tag: %s -> %s: %s\", key, value, err)\n\t}\n\n\treturn nil\n}\n\n// DeleteTag create tag by key and value\nfunc (c *remoteClient) DeleteTag(key, value string) error {\n\trequest := tag.NewDeleteTagRequest()\n\trequest.TagKey = &key\n\trequest.TagValue = &value\n\n\t_, err := c.tagClient.DeleteTag(request)\n\tlog.Printf(\"[DEBUG] delete tag %s:%s: error: %v\", key, value, err)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to delete tag: %s -> %s: %s\", key, value, err)\n\t}\n\n\treturn nil\n}\n","sourceCodeStart":428,"sourceCodeEnd":451,"githubUrl":"https://github.com/hashicorp/terraform/blob/d32a084675427f5ac3f7d2868578ef8b2c1dc525/internal/backend/remote-state/cos/client.go#L428-L451","documentation":"Returned by DeleteTag() when the Tencent Cloud Tag service rejects the DeleteTag call. The COS backend removes the distributed lock tag during Unlock; if the tag API call fails, the unlock cannot complete and the lock may remain, blocking subsequent runs. The key, value, and underlying API error are surfaced.","triggerScenarios":"c.tagClient.DeleteTag(request) returns a non-nil error. Causes: missing/denied `tag:DeleteTag` permission, the tag was already deleted by a concurrent unlock (race), the tag service is degraded, or the tag key/value does not match what exists.","commonSituations":"Sub-account lacks Tag delete permission; two Terraform runs racing to unlock; the lock tag was manually removed mid-unlock; transient Tag API 5xx; cosUnlock retries up to 30 times then surfaces the last error.","solutions":["Inspect the wrapped API error for the Tencent error code.","Grant `tag:DeleteTag` (and `tag:DescribeTags`) to the principal.","If the tag is already gone, treat the unlock as complete (the retry loop in cosUnlock should converge, but if not, force-unlock).","For transient failures, retry `terraform force-unlock <ID>` after the Tag service recovers."],"exampleFix":"// before: principal has cos:* but not tag:DeleteTag, unlock fails leaving state locked\n// after: add Tag delete permission\n{\n  \"statement\":[{\"effect\":\"allow\",\"action\":[\"tag:CreateTag\",\"tag:DeleteTag\",\"tag:DescribeTags\"],\"resource\":\"*\"}]\n}","handlingStrategy":"validation","validationCode":"// Before relying on unlock, confirm Tag delete permission\nfunc canDeleteLockTag(ctx context.Context, tagClient *tag.Client, key, value string) error {\n    req := tag.NewDeleteTagRequest()\n    req.TagKey, req.TagValue = &key, &value\n    _, err := tagClient.DeleteTag(req)\n    if err != nil && (strings.Contains(err.Error(), \"AuthFailure\") || strings.Contains(err.Error(), \"Unauthorized\")) {\n        return fmt.Errorf(\"principal lacks tag:DeleteTag: %w\", err)\n    }\n    return nil // not-found is acceptable for a probe\n}","typeGuard":"func isTagDeletePermissionError(err error) bool {\n    s := err.Error()\n    return strings.Contains(s, \"AuthFailure\") || strings.Contains(s, \"UnauthorizedOperation\")\n}","tryCatchPattern":"// cosUnlock already retries 30x; if it still fails, classify:\nif isTagDeletePermissionError(err) {\n    // not retryable — surface clear guidance\n    return fmt.Errorf(\"grant tag:DeleteTag to allow unlock: %w\", err)\n}","preventionTips":["Grant the Tag service delete/describe permissions alongside COS permissions.","Avoid racing two Terraform runs against the same state (both will fight over the lock tag).","Do not manually remove lock tags unless you are certain no run is active.","After any unlock failure, run `terraform force-unlock <ID>` once the permission/transient issue is resolved."],"tags":["terraform","cos","tencent-cloud","tag","permissions","state-lock","unlock","remote-state","go"],"backgroundTag":null,"analyzedSha":"d32a084675427f5ac3f7d2868578ef8b2c1dc525","analyzedAt":"2026-08-11T18:43:52.779Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}