hashicorp/terraform · error
failed to create tag: %s -> %s: %s
Error message
failed to create tag: %s -> %s: %s
What it means
Raised by CreateTag() when the Tencent Cloud Tag service's CreateTag API returns an error. Tags are used by the COS backend as a distributed lock (lockTagKey='tencentcloud-terraform-lock') keyed by an md5 of bucket:lockfile, so a failure to create the lock tag means the state lock could not be acquired.
Source
Thrown at internal/backend/remote-state/cos/client.go:431
tagKey := response.Response.Tags[0].TagKey
tagValue := response.Response.Tags[0].TagValue
exists = key == *tagKey && value == *tagValue
return
}
// CreateTag create tag by key and value
func (c *remoteClient) CreateTag(key, value string) error {
request := tag.NewCreateTagRequest()
request.TagKey = &key
request.TagValue = &value
_, err := c.tagClient.CreateTag(request)
log.Printf("[DEBUG] create tag %s:%s: error: %v", key, value, err)
if err != nil {
return fmt.Errorf("failed to create tag: %s -> %s: %s", key, value, err)
}
return nil
}
// DeleteTag create tag by key and value
func (c *remoteClient) DeleteTag(key, value string) error {
request := tag.NewDeleteTagRequest()
request.TagKey = &key
request.TagValue = &value
_, err := c.tagClient.DeleteTag(request)
log.Printf("[DEBUG] delete tag %s:%s: error: %v", key, value, err)
if err != nil {
return fmt.Errorf("failed to delete tag: %s -> %s: %s", key, value, err)
}
return nilView on GitHub (pinned to c9def3e214)
Solutions
- Grant the credentials QcloudTAGFullAccess (or scoped tag:CreateTag/tag:DeleteTag/tag:DescribeTags) on the Tag service.
- Retry the apply — transient STS/rate-limit failures often clear.
- Confirm the tag region matches the Tag service region the SDK is using.
- If a stale lock tag from a crashed run is the cause, locate and remove it via the Tag console, then re-run.
Example fix
# attach Tag policy to the IAM principal used by the backend # policy: QcloudTAGFullAccess (or scoped QcloudTAGDataFullAccess is insufficient for Create/Delete) # then retry terraform apply
Defensive patterns
Strategy: retry
Validate before calling
// Verify the principal has Tag service rights before locking.
func canUseTagService(ctx context.Context, t *tag.Client, key string) error {
req := tag.NewDescribeTagsRequest()
req.TagKey = &key
_, err := t.DescribeTags(req)
return err
} Try / catch
if err := c.Lock(info); err != nil {
// tag create failed: grant QcloudTAGFullAccess / tag:CreateTag, refresh STS, retry
} Prevention
- Grant QcloudTAGFullAccess (Create/Describe/Delete) to the backend principal.
- Refresh STS tokens before they expire during long applies.
- Keep tag count under the Tencent quota.
When it happens
Trigger: At client.go:428-431: c.tagClient.CreateTag(request) returns err. Triggered during Lock() (via cosLock -> CreateTag). Occurs when the tag principal lacks QcloudTAGFullAccess/tag:CreateTag, the tag key/value already exists, STS token expired, or the Tag API region/service is unavailable.
Common situations: Backend credentials have COS rights but not Tag service rights; secret key is for a sub-account without tag permissions; STS temporary credentials expired mid-run; tag quota exceeded; Tag API rate-limited.
Related errors
- failed to delete tag: %s -> %s: %s
- failed to empty bucket %v: %v
- %q cannot be lower than %d: %d
- %q cannot be higher than %d: %d
- Failed to lock cos state: %s
AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07).
Data as JSON: /api/errors/70daa666867a5b53.
Report an issue: GitHub.