hashicorp/terraform · error
Unlocking the state file on TencentCloud cos backend failed:
Error message
Unlocking the state file on TencentCloud cos backend failed: Error message: %v Lock ID (gen): %s You may have to force-unlock this state in order to use it again. The TencentCloud backend acquires a lock during initialization to ensure the initial state file is created.
What it means
The unlockErrMsg constant (cos/backend_state.go:121), emitted by the lockUnlock() helper inside StateMgr() when the cleanup Unlock of the initialization lock itself fails. It warns that the state is now locked and must be force-unlocked before it can be used again, and includes the lock ID (gen) so the user knows what to unlock.
Source
Thrown at internal/backend/remote-state/cos/backend_state.go:121
break
}
}
if !exists {
log.Printf("[DEBUG] workspace %v not exists", name)
// take a lock on this state while we write it
lockInfo := statemgr.NewLockInfo()
lockInfo.Operation = "init"
lockId, err := c.Lock(lockInfo)
if err != nil {
return nil, diags.Append(fmt.Errorf("Failed to lock cos state: %s", err))
}
// Local helper function so we can call it multiple places
lockUnlock := func(e error) error {
if err := stateMgr.Unlock(lockId); err != nil {
return fmt.Errorf(unlockErrMsg, err, lockId)
}
return e
}
// Grab the value
if err := stateMgr.RefreshState(); err != nil {
err = lockUnlock(err)
return nil, diags.Append(err)
}
// If we have no state, we have to create an empty state
if v := stateMgr.State(); v == nil {
if err := stateMgr.WriteState(states.NewState()); err != nil {
err = lockUnlock(err)
return nil, diags.Append(err)
}
if err := stateMgr.PersistState(nil); err != nil {
err = lockUnlock(err)View on GitHub (pinned to c9def3e214)
Solutions
- Run `terraform force-unlock <Lock ID (gen)>` using the ID printed in the message.
- Confirm the COS credentials still have object-delete and tag-delete permissions.
- Manually remove the lock file object and the tencentcloud-terraform-lock tag if force-unlock also fails.
- Re-run `terraform init` once the lock is cleared.
Example fix
// error includes: Lock ID (gen): <id> terraform force-unlock <id> terraform init
Defensive patterns
Strategy: try-catch
Try / catch
// After a failed init, attempt force-unlock using the reported lock ID
if diags.HasErrors() && strings.Contains(diags.Err().Error(), "Unlocking the state file on TencentCloud cos backend failed") {
id := extractLockID(diags.Err().Error())
_ = forceUnlockCos(id) // terraform force-unlock <id>
} Prevention
- Run `terraform force-unlock <Lock ID (gen)>` promptly when this message appears.
- Verify COS delete permissions so future cleanups succeed.
- Avoid killing terraform mid-init, which leaves locks behind.
When it happens
Trigger: During StateMgr() init, after a write/persist failure, lockUnlock() calls stateMgr.Unlock(lockId) which returns an error; the formatted message is returned wrapping that error.
Common situations: Transient COS failure during init cleanup; credentials expired mid-init; the lock object was already removed by a concurrent process so the unlock call errors; permissions to delete the lock object are missing.
Related errors
- lock id mismatch, %v != %v
- Failed to lock cos state: %s
- lock file %s exists
- lock file %s not exists
- failed to delete tag: %s -> %s: %s
AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07).
Data as JSON: /api/errors/7022c3a97e6df356.
Report an issue: GitHub.