{"record":{"id":"a5c6461b2770eeaa","repo":"hashicorp/terraform","slug":"error-deleting-state-s-v","errorCode":null,"errorMessage":"error deleting state %s: %#v","messagePattern":"error deleting state (.+?): %#v","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/backend/remote-state/oss/client.go","lineNumber":144,"sourceCode":"\tif err := c.putMD5(sum[:]); err != nil {\n\t\t// if this errors out, we unfortunately have to error out altogether,\n\t\t// since the next Get will inevitably fail.\n\t\treturn diags.Append(fmt.Errorf(\"failed to store state MD5: %s\", err))\n\t}\n\treturn diags\n}\n\nfunc (c *RemoteClient) Delete() tfdiags.Diagnostics {\n\tvar diags tfdiags.Diagnostics\n\tbucket, err := c.ossClient.Bucket(c.bucketName)\n\tif err != nil {\n\t\treturn diags.Append(fmt.Errorf(\"error getting bucket %s: %#v\", c.bucketName, err))\n\t}\n\n\tlog.Printf(\"[DEBUG] Deleting remote state from OSS: %#v\", c.stateFile)\n\n\tif err := bucket.DeleteObject(c.stateFile); err != nil {\n\t\treturn diags.Append(fmt.Errorf(\"error deleting state %s: %#v\", c.stateFile, err))\n\t}\n\n\tif err := c.deleteMD5(); err != nil {\n\t\tlog.Printf(\"[WARN] Error deleting state MD5: %s\", err)\n\t}\n\treturn diags\n}\n\nfunc (c *RemoteClient) Lock(info *statemgr.LockInfo) (string, error) {\n\tif c.otsTable == \"\" {\n\t\treturn \"\", nil\n\t}\n\n\tinfo.Path = c.lockPath()\n\n\tif info.ID == \"\" {\n\t\tlockID, err := uuid.GenerateUUID()\n\t\tif err != nil {","sourceCodeStart":126,"sourceCodeEnd":162,"githubUrl":"https://github.com/hashicorp/terraform/blob/c9def3e214014c1188faabfc4a5bde5095139765/internal/backend/remote-state/oss/client.go#L126-L162","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before: AccessDenied on delete\n// grant policy:\n//   Effect: Allow, Action: \"oss:DeleteObject\", Resource: \"acs:oss:*:*:tf-state/tf-state-prefix/*\"\n// then:\nterraform workspace delete dev","handlingStrategy":"validation","validationCode":"// Check the object exists and credentials can delete before terraform workspace delete.\nfunc canDelete(bucket *oss.Bucket, key string) error {\n    exists, err := bucket.IsObjectExist(key)\n    if err != nil { return err }\n    if !exists { return fmt.Errorf(\"%s already gone; clean OTS rows manually\", key) }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"// Distinguish NoSuchKey (already gone) from AccessDenied.\nif oe, ok := err.(oss.ServiceError); ok && oe.StatusCode == 404 {\n    // object already absent; safe to proceed / clean OTS\n}\nif oe, ok := err.(oss.ServiceError); ok && oe.StatusCode == 403 {\n    return grantDeleteObjectPolicy()\n}","preventionTips":["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."],"tags":["alibaba-cloud","oss","remote-state","object-delete","permissions","go"],"analyzedSha":"c9def3e214014c1188faabfc4a5bde5095139765","analyzedAt":"2026-08-07T15:39:49.278Z","schemaVersion":2},"datasetVersion":"2026-08-07T21:17:07.882Z"}