This error occurs when Terraform attempts to create a resource that already exists in your infrastructure. The underlying provider returns a 409 conflict, indicating the resource name or identifier is not available.
The 'resource already exists' error happens when there's a mismatch between Terraform's state file and the actual infrastructure. Terraform's state tracks all resources it manages. When you run 'terraform apply', Terraform compares its state with your configuration and attempts to create new resources. If the provider reports that a resource with that name or identifier already exists, Terraform cannot proceed because the resource creation would fail. This commonly occurs when: resources are manually created outside of Terraform; the state file is out of sync with reality; a previous 'terraform destroy' didn't fully remove the resource; or you're using duplicate resource identifiers in your configuration.
Read the error message carefully to identify which resource is causing the conflict. The error typically includes the resource type (e.g., 'aws_s3_bucket', 'azurerm_resource_group') and sometimes the name.
Error: Error creating bucket: BucketAlreadyOwnedByYou
on main.tf line 5, in resource "aws_s3_bucket" "example":Check your cloud provider's console or CLI to confirm the resource actually exists:
AWS: aws s3api head-bucket --bucket my-bucket-name
Azure: az resource show --resource-group mygroup --name myresource --resource-type Microsoft.Storage/storageAccounts
GCP: gcloud compute instances list
Note the resource's exact identifier (name, ID, or ARN) from the provider.
Inspect what Terraform believes exists in your state file:
terraform state list
terraform state show 'resource.type.name'If the resource appears in state but with different attributes, compare them to what exists in your provider. If it doesn't appear in state at all, proceed to import it.
The most reliable solution is to import the existing resource into Terraform's management:
terraform import 'resource.type.name' 'resource-id-or-name'Example for AWS S3:
terraform import 'aws_s3_bucket.example' 'my-bucket-name'Example for Azure:
terraform import 'azurerm_resource_group.example' '/subscriptions/{subscription-id}/resourceGroups/{rg-name}'Terraform will query the provider, fetch the resource details, and add it to your state file. Your configuration must already define the resource block with the correct type and name.
After importing, run 'terraform plan' to see what differences exist between your configuration and the actual resource:
terraform planUpdate your .tf files to match the resource's actual attributes. For example, if you defined versioning = true but the actual resource has versioning disabled, update your config or adjust your expectations.
Keep iterating until 'terraform plan' shows no changes needed.
If import doesn't work or the resource is managed externally long-term, you can remove it from Terraform's management:
terraform state rm 'resource.type.name'This removes the resource from your state file without deleting it from your provider. Use this only if you don't intend to manage the resource with Terraform. You can always re-import later.
If the resource is safe to delete and recreate, delete it manually from your provider, then run:
terraform applyUse this only for non-critical resources or in development environments. For production resources, prefer importing. To delete the resource from your provider:
AWS: aws s3api delete-bucket --bucket my-bucket-name
Azure: az resource delete --resource-group mygroup --name myresource --resource-type Microsoft.Storage/storageAccounts
After deletion, Terraform will recreate it according to your configuration.
State Locking: If working in a team, enable state locking to prevent concurrent modifications. Use remote backends (Terraform Cloud, S3 with DynamoDB, Azure Storage) to ensure everyone operates on the same state.
Lifecycle Policies: Use lifecycle { prevent_destroy = true } or lifecycle { ignore_changes = [...] } to prevent accidental resource recreation or to ignore provider-side changes that don't matter to you.
Provider-Specific Uniqueness: Some resources have global uniqueness requirements (e.g., AWS S3 bucket names, Azure storage account names). If recreating, you may need to use a new name.
Deposed Objects: If a resource replacement in progress was interrupted, Terraform may have 'deposed' objects. Use terraform plan to identify them and terraform apply -target='resource.type.name' to complete the replacement.
Error: Error rendering template: template not found
How to fix "template not found" error in Terraform
Error: Error generating private key
How to fix 'Error generating private key' in Terraform
Error creating Kubernetes Service: field is immutable
How to fix "field is immutable" errors in Terraform
Error: Error creating local file: open: permission denied
How to fix "Error creating local file: permission denied" in Terraform
Error: line endings have changed from CRLF to LF
Line endings have changed from CRLF to LF in Terraform