Skip to content
Latchkey

Terraform "Invalid for_each argument" in CI

for_each needs a map or set of strings whose keys are known at plan time. A value that is null, the wrong type, or derived from a not-yet-created resource fails this check.

What this error means

terraform plan/apply reports an invalid for_each argument, either complaining the value is not a map/set of strings or that it depends on resource attributes that cannot be determined until apply.

terraform
Error: Invalid for_each argument

  on main.tf line 10, in resource "aws_route53_record" "rec":
  10:   for_each = toset([for s in aws_instance.web : s.private_ip])

The "for_each" set includes values derived from resource attributes that
cannot be determined until apply.

Common causes

Keys depend on computed values

for_each keys come from attributes of resources not yet created, so they are unknown at plan time.

Wrong type passed to for_each

A list, null, or a map with non-string values does not satisfy the map/set-of-strings requirement.

How to fix it

Key on statically known values

Use keys that are known at plan time (input variables, locals), not computed attributes.

Terraform
# instead of keying on a computed IP, key on a known name:
for_each = { for k, v in var.hosts : k => v }

Coerce the type or split the apply

  1. Wrap the value in toset(...)/tomap(...) only when the contents are already known.
  2. If keys truly depend on a created resource, -target that resource first, then apply the for_each block.
  3. Restructure so the key source is an input rather than a computed output.

How to prevent it

  • Key for_each on inputs and locals, never on computed attributes.
  • Validate variable shapes with type constraints.
  • Avoid chaining for_each on another resource's outputs.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →