OpenTofu Error: 'Invalid index' key does not identify an element
Fix OpenTofu's 'Invalid index: The given key does not identify an element in this collection value' error: handle missing map keys, out-of-range list indexes, and for_each keys.
- #opentofu
- #terraform
- #iac
- #troubleshooting
- #errors
Stuck on this OpenTofu error? Get the free incident triage checklist
A one-page PDF — the exact steps to isolate, fix, and verify a production error like this one. No spam, unsubscribe anytime.
Exact Error Message
╷
│ Error: Invalid index
│
│ on outputs.tf line 3, in output "primary_subnet_id":
│ 3: value = aws_subnet.this["public-c"].id
│ ├────────────────
│ │ aws_subnet.this is object with 2 attributes
│
│ The given key does not identify an element in this collection value.
╵
The same error appears for out-of-range list access, for example var.azs[5] when the list has three elements.
What It Means
Invalid index means the collection you indexed exists, but the key or position you asked for is not in it. For a map or a for_each resource, the string key is absent; for a list or a count resource, the numeric index is out of range.
Unlike some languages, OpenTofu does not return a null for a missing key — it fails the plan. The error message often prints how many elements the collection actually has, which is the fastest clue to what went wrong.
Common Causes
- Referencing a
for_eachinstance with a key that was never in thefor_eachset (a typo or a removed entry). - Indexing a list past its last element (
list[3]on a three-item list, which stops at index 2). - Reading a map key that does not exist in the variable or
local. - A
count-based resource where the index is larger thancount - 1. - Assuming an optional map entry is present when the input omitted it.
- Drift between the keys you defined and the keys you reference after refactoring.
Diagnostic Commands
Run plan to get the file, line, and the collection’s real size:
tofu plan
Print the collection’s keys in the console to see what is actually available:
tofu console
> keys(var.cidr_by_az)
For a for_each resource, list the instance keys currently in state:
tofu state list | grep aws_subnet
Check the length of a list before indexing into it:
tofu console
> length(var.azs)
Step-by-Step Resolution
-
Read the error. It shows the collection and, for objects, how many attributes it holds. Compare that against the key you used.
-
List the valid keys so you can correct the reference:
echo 'keys(aws_subnet.this)' | tofu console
- Fix the key to one that exists. In the example,
public-cwas never created, so use a real key:
output "primary_subnet_id" {
value = aws_subnet.this["public-a"].id
}
- If the key may legitimately be absent, use
lookup()ortry()to supply a fallback instead of failing:
value = lookup(var.cidr_by_az, "public-c", null)
value = try(aws_subnet.this["public-c"].id, null)
- For lists, guard the index against the length:
value = length(var.azs) > 2 ? var.azs[2] : var.azs[0]
- If the missing key means an instance should exist, add it to the
for_eachset and re-plan:
tofu plan
Plan: 1 to add, 0 to change, 0 to destroy.
Prevention
- Reference
for_eachinstances only by keys you know are in the set; keep the set definition and its consumers in the same module for visibility. - Use
lookup()with a default ortry()when a map key is genuinely optional. - Validate list length before positional indexing, or switch to maps with named keys to avoid index math entirely.
- After removing an entry from a
for_eachor shrinking a list, grep the config for now-stale references. - Prefer named map keys over numeric list indexes so references read intent rather than position.
Related Errors
Invalid for_each argument— thefor_eachcollection itself is the wrong type or unknown until apply.Unsupported attribute— the object exists but the attribute after the dot is not in its schema.Reference to undeclared resource— the collection object itself does not exist.Call to function "element" failed— a related out-of-range access via theelementfunction.
Frequently Asked Questions
Why doesn’t OpenTofu just return null for a missing key? By design, direct indexing is strict and fails on a missing key; use lookup() or try() when you want a null or default instead.
How do I see which keys a for_each resource has? Run tofu console and evaluate keys(<resource>), or use tofu state list to see the instance addresses already tracked.
What is the safest way to read an optional map value? lookup(map, "key", default) returns the default when the key is absent, avoiding the error entirely.
Why did this appear only after I refactored? Removing an entry from a for_each set or shortening a list leaves references to keys or indexes that no longer exist, which then fail on the next plan. For reusable troubleshooting prompts, browse the prompt library, and for more fixes see the OpenTofu guides.
Fixed it? Get 500 OpenTofu & DevOps AI prompts — free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.
Did this fix your issue?
Get 500 Battle-Tested DevOps AI Prompts — Free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.