hashicorp/terraform · error · statemgr.LockError
lock file %s exists
Error message
lock file %s exists
What it means
Raised by remoteClient.Lock() (cos/client.go:98) after the COS tag lock is acquired. Lock() then checks whether the lock file object already exists in the bucket; if it does, another Terraform run already holds the state lock, so this run must abort and release its tag lock.
Source
Thrown at internal/backend/remote-state/cos/client.go:98
}
// Lock lock remote state file for writing
func (c *remoteClient) Lock(info *statemgr.LockInfo) (string, error) {
log.Printf("[DEBUG] lock remote state file %s", c.lockFile)
err := c.cosLock(c.bucket, c.lockFile)
if err != nil {
return "", c.lockError(err)
}
defer c.cosUnlock(c.bucket, c.lockFile)
exists, _, _, err := c.getObject(c.lockFile)
if err != nil {
return "", c.lockError(err)
}
if exists {
return "", c.lockError(fmt.Errorf("lock file %s exists", c.lockFile))
}
info.Path = c.lockFile
data, err := json.Marshal(info)
if err != nil {
return "", c.lockError(err)
}
check := fmt.Sprintf("%x", md5.Sum(data))
err = c.putObject(c.lockFile, data)
if err != nil {
return "", c.lockError(err)
}
return check, nil
}
// Unlock unlock remote state fileView on GitHub (pinned to c9def3e214)
Solutions
- Wait for the other terraform run to finish and release the lock, then retry.
- If the holder is gone, run `terraform force-unlock <lock-id>` to remove the stale lock file.
- As a last resort, delete the lock file object and the tencentcloud-terraform-lock tag in the COS console, then retry.
Example fix
// after 'lock file ... exists' terraform force-unlock <lock-id> terraform apply
Defensive patterns
Strategy: retry
Validate before calling
// Pre-check whether a lock file already exists before attempting Lock
func alreadyLocked(c *remoteClient) bool {
exists, _, _, _ := c.getObject(c.lockFile)
return exists
} Try / catch
// Retry Lock when contention is transient; force-unlock if stale
for attempt := 0; attempt < 3; attempt++ {
_, err := c.Lock(info)
if err == nil { break }
if !strings.Contains(err.Error(), "lock file") { return err }
time.Sleep(time.Duration(attempt+1) * 2 * time.Second)
} Prevention
- Serialize terraform runs per workspace to avoid lock contention.
- Clear stale lock files with `terraform force-unlock` after crashes.
- Never delete the lock file manually unless force-unlock fails.
When it happens
Trigger: Lock() calls getObject(c.lockFile) and exists==true, meaning the <state>.tflock object is present from a prior/active lock holder.
Common situations: Concurrent terraform runs on the same workspace; a previous run crashed and left the lock file object behind; a force-unlock was not performed after a crash.
Related errors
- Failed to lock cos state: %s
- lock file %s not exists
- default state is not allowed to be deleted
- Unlocking the state file on TencentCloud cos backend failed:
- state name not allow to be empty
AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07).
Data as JSON: /api/errors/5a25850c10d266cb.
Report an issue: GitHub.