Choosing between count and for_each affects how Terraform tracks resources. Using the wrong approach or mixing them incorrectly causes various errors.
Introduction
count creates resources with numeric indices (0, 1, 2...), while for_each uses map keys. Common errors include:
Error: Invalid index: 3 is out of bounds
Error: Each value has distinct keys: "a", "b"
Error: Cannot use count and for_each togetherSymptoms
Common error messages include:
Error: Invalid index: 3 is out of bounds
Error: Each value has distinct keys: "a", "b"
Error: Cannot use count and for_each together3 is out of bounds for a list of length 3. ```
```hcl # Problem: count doesn't match list length variable "names" { default = ["a", "b", "c"] # 3 items }
resource "aws_instance" "web" { count = 4 # Trying to create 4 instances name = var.names[count.index] # Fails at index 3 } ```
Common Causes
- Configuration misconfiguration
- Missing or incorrect credentials
- Network connectivity issues
- Version compatibility problems
- Resource exhaustion or limits
- Permission or access denied
Step-by-Step Fix
- 1.Check logs for specific error messages
- 2.Verify configuration settings
- 3.Test network connectivity
- 4.Review recent changes
- 5.Apply corrective action
- 6.Verify the fix
Issue 1: Index Out of Bounds
When using count and the list changes, indices shift.
3 is out of bounds for a list of length 3. ```
Root Cause:
The count value doesn't match the list length: ```hcl # Problem: count doesn't match list length variable "names" { default = ["a", "b", "c"] # 3 items }
resource "aws_instance" "web" { count = 4 # Trying to create 4 instances name = var.names[count.index] # Fails at index 3 } ```
Solution:
Synchronize count with your data: ```hcl # Use length to ensure consistency variable "names" { type = list(string) default = ["web-1", "web-2", "web-3"] }
resource "aws_instance" "web" { count = length(var.names) name = var.names[count.index]
ami = var.ami_id instance_type = "t3.micro" tags = { Name = var.names[count.index] } } ```
Issue 2: Resources Replaced When List Changes
Removing an item from the middle of a list causes unwanted replacements.
Error Scenario: ``` # Before: ["a", "b", "c"] # Remove "b", becomes: ["a", "c"]
# Terraform plan shows: - aws_instance.web[1] will be destroyed - aws_instance.web[2] will be replaced (index changes to [1]) ```
Solution:
Use for_each with maps instead of count with lists:
```hcl
# Bad: Count with list causes index shifts
variable "instances" {
type = list(string)
default = ["web-a", "web-b", "web-c"]
}
# Good: For_each with map maintains stable keys variable "instances" { type = map(object({ ami = string type = string })) default = { web-a = { ami = "ami-123", type = "t3.micro" } web-b = { ami = "ami-123", type = "t3.micro" } web-c = { ami = "ami-123", type = "t3.micro" } } }
resource "aws_instance" "web" { for_each = var.instances
ami = each.value.ami instance_type = each.value.type tags = { Name = each.key # "web-a", "web-b", etc. } } ```
Now removing "web-b" only destroys that instance without affecting others.
Issue 3: Converting Count to For Each
Migrating existing resources from count to for_each.
Error Example:
``
Error: Instance cannot be destroyed
Resource aws_instance.web[0] has lifecycle.prevent_destroy
Solution:
Use targeted approach for safe migration: ```bash # 1. Import existing resources with their new keys terraform import 'aws_instance.web["web-a"]' i-aaa111 terraform import 'aws_instance.web["web-b"]' i-bbb222 terraform import 'aws_instance.web["web-c"]' i-ccc333
# 2. Remove old count-based state terraform state rm 'aws_instance.web[0]' terraform state rm 'aws_instance.web[1]' terraform state rm 'aws_instance.web[2]'
# 3. Update configuration to use for_each # 4. Run terraform plan to verify no changes ```
Or use the moved block (Terraform 1.1+): ```hcl moved { from = aws_instance.web[0] to = aws_instance.web["web-a"] }
moved { from = aws_instance.web[1] to = aws_instance.web["web-b"] }
moved { from = aws_instance.web[2] to = aws_instance.web["web-c"] } ```
Issue 4: Duplicate Keys in For Each
Using a list that contains duplicates with for_each.
Error Example:
``
Error: Duplicate key in for_each
on main.tf line 5:
5: for_each = toset(var.names)
The given for_each value has duplicate keys: "web-server".
Root Cause:
``hcl
variable "names" {
default = ["web-server", "web-server", "db-server"] # Duplicate!
}
Solution:
Ensure unique values before using with for_each: ```hcl # Use distinct() to remove duplicates resource "aws_instance" "web" { for_each = toset(distinct(var.names))
ami = var.ami_id instance_type = "t3.micro" tags = { Name = each.key } }
# Or use a map for guaranteed unique keys variable "servers" { type = map(string) default = { "web-1" = "ami-abc123" "web-2" = "ami-abc123" "db-1" = "ami-def456" } }
resource "aws_instance" "server" { for_each = var.servers ami = each.value # ... } ```
Issue 5: Conditional Count with Zero
Using count conditionally where the value can be zero.
Error Example:
``
Error: Invalid index on main.tf line 20:
20: subnet_id = aws_subnet.public[count.index].id
aws_subnet.public is empty tuple
Root Cause: ```hcl # When count = 0, no resources exist resource "aws_subnet" "public" { count = var.create_public_subnets ? 3 : 0 # ... }
resource "aws_route_table_association" "public" { count = length(aws_subnet.public) subnet_id = aws_subnet.public[count.index].id # Fails if count was 0 # ... } ```
Solution:
Handle the conditional properly: ```hcl # Option 1: Use dynamic blocks instead resource "aws_route_table_association" "public" { count = var.create_public_subnets ? length(var.public_subnet_cidrs) : 0
subnet_id = aws_subnet.public[count.index].id route_table_id = aws_route_table.public[0].id }
# Option 2: Use for_each with conditional resource "aws_subnet" "public" { for_each = var.create_public_subnets ? var.public_subnet_config : {}
vpc_id = aws_vpc.main.id cidr_block = each.value.cidr_block } ```
Issue 6: Mixing Count and For Each in Same Resource
Attempting to use both meta-arguments.
Error Example:
``
Error: Invalid resource configuration on main.tf line 5:
Cannot use both count and for_each in the same resource.
Solution:
Choose one approach: ```hcl # Wrong resource "aws_instance" "web" { count = 3 for_each = toset(["a", "b"]) # Cannot use both! }
# Right: Use count for simple numeric iteration resource "aws_instance" "web" { count = 3 tags = { Name = "web-${count.index}" } }
# Right: Use for_each for key-based iteration resource "aws_instance" "web" { for_each = toset(["a", "b", "c"]) tags = { Name = each.key } } ```
Verification
Test your configuration: ```bash # Validate syntax terraform validate
# See what will be created terraform plan
# For existing resources, verify state terraform state list ```
Check resource addressing: ```bash # Count-based resources terraform state show 'aws_instance.web[0]'
# For_each-based resources terraform state show 'aws_instance.web["web-a"]' ```
Prevention
- 1.Use
for_eachwhen resources have natural keys (environments, regions, named instances) - 2.Use
countonly for simple homogeneous resources where order matters - 3.Never mix
countandfor_eachin the same resource - 4.Use
movedblocks when converting between approaches - 5.Always use
length()with lists when usingcount - 6.Validate with
terraform planbefore applying
Related Articles
- [Fix Fix Terraform API Token Issue in Terraform](fix-terraform-api-token)
- [Fix Terraform Apply Timeout - Resource Creation Hanging Indefinitely](fix-terraform-apply-timeout)
- [How to Fix Terraform AWS Provider Errors](fix-terraform-aws-provider)
- [Fix Fix Terraform Azure Backend Issue in Terraform](fix-terraform-azure-backend)
- [Fix Terraform Backend Configuration Error - State Backend Setup Failure](fix-terraform-backend-config-error)
<script type="application/ld+json"> { "@context": "https://schema.org", "@type": "TechArticle", "headline": "How to Fix Terraform Count vs For Each Issues", "description": "Learn to fix Terraform count and for_each errors including index out of bounds, key issues, and resource replacement problems.", "url": "https://www.fixwikihub.com/fix-terraform-count-vs-for-each", "publisher": { "@type": "Organization", "name": "FixWikiHub", "url": "https://www.fixwikihub.com" }, "author": { "@type": "Person", "name": "FixWikiHub Editorial Team" }, "datePublished": "2025-11-17T00:37:40.406Z", "dateModified": "2025-11-17T00:37:40.406Z" } </script>