hashicorp/terraform · error
error deleting state %s: %#v
Error message
error deleting state %s: %#v
What it means
In RemoteClient.Delete() (client.go:143-144), bucket.DeleteObject(stateFile) failed. %#v dumps the OSS SDK error. This removes the workspace's state object (and best-effort its MD5 via deleteMD5, logged-only at line 148).
Source
Thrown at internal/backend/remote-state/oss/client.go:144
if err := c.putMD5(sum[:]); err != nil {
// if this errors out, we unfortunately have to error out altogether,
// since the next Get will inevitably fail.
return diags.Append(fmt.Errorf("failed to store state MD5: %s", err))
}
return diags
}
func (c *RemoteClient) Delete() tfdiags.Diagnostics {
var diags tfdiags.Diagnostics
bucket, err := c.ossClient.Bucket(c.bucketName)
if err != nil {
return diags.Append(fmt.Errorf("error getting bucket %s: %#v", c.bucketName, err))
}
log.Printf("[DEBUG] Deleting remote state from OSS: %#v", c.stateFile)
if err := bucket.DeleteObject(c.stateFile); err != nil {
return diags.Append(fmt.Errorf("error deleting state %s: %#v", c.stateFile, err))
}
if err := c.deleteMD5(); err != nil {
log.Printf("[WARN] Error deleting state MD5: %s", err)
}
return diags
}
func (c *RemoteClient) Lock(info *statemgr.LockInfo) (string, error) {
if c.otsTable == "" {
return "", nil
}
info.Path = c.lockPath()
if info.ID == "" {
lockID, err := uuid.GenerateUUID()
if err != nil {View on GitHub (pinned to c9def3e214)
Solutions
- If the object is already gone, remove the dangling OTS digest/lock rows manually or accept the workspace list ghost entry.
- Grant the credentials oss:DeleteObject on the bucket/prefix.
- Retry terraform workspace delete after confirming OSS availability.
- Check bucket protection policies (e.g. WORM, versioning suspend) that prevent DeleteObject.
Example fix
// before: AccessDenied on delete // grant policy: // Effect: Allow, Action: "oss:DeleteObject", Resource: "acs:oss:*:*:tf-state/tf-state-prefix/*" // then: terraform workspace delete dev
Defensive patterns
Strategy: validation
Validate before calling
// Check the object exists and credentials can delete before terraform workspace delete.
func canDelete(bucket *oss.Bucket, key string) error {
exists, err := bucket.IsObjectExist(key)
if err != nil { return err }
if !exists { return fmt.Errorf("%s already gone; clean OTS rows manually", key) }
return nil
} Try / catch
// Distinguish NoSuchKey (already gone) from AccessDenied.
if oe, ok := err.(oss.ServiceError); ok && oe.StatusCode == 404 {
// object already absent; safe to proceed / clean OTS
}
if oe, ok := err.(oss.ServiceError); ok && oe.StatusCode == 403 {
return grantDeleteObjectPolicy()
} Prevention
- Grant oss:DeleteObject on the state prefix.
- Avoid deleting state objects out-of-band; let terraform manage them.
- Review bucket protection (WORM/versioning) policies that block DeleteObject.
When it happens
Trigger: DeleteObject returns NoSuchKey (already gone), AccessDenied, or a service error. Common when deleting a workspace whose state object was already removed manually, or credentials lack oss:DeleteObject.
Common situations: Workspace state object deleted out-of-band before terraform workspace delete; RAM policy missing oss:DeleteObject; bucket versioning/safe-delete policies blocking deletion; transient OSS error.
Related errors
- failed to upload state %s: %#v
- estimating object %s is exist got an error: %#v
- error getting bucket: %#v
- state data in OSS does not have the expected content. This
- error getting bucket: %#v
AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07).
Data as JSON: /api/errors/a5c6461b2770eeaa.
Report an issue: GitHub.