Skip to content
DevOps AI ToolKit
Newsletter
All guides
AI for OpenTofu By James Joyner IV · · 8 min read Last reviewed Jul 2026

OpenTofu Error: 'depends on resource attributes that cannot be determined until apply'

Quick answer

Fix OpenTofu's count/for_each 'depends on resource attributes that cannot be determined until apply' error: use static keys, -target, or split the apply into stages.

  • #opentofu
  • #terraform
  • #iac
  • #troubleshooting
  • #errors
Free toolkit

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 count argument

│   on main.tf line 24, in resource "aws_route53_record" "app":
│   24:   count = length(aws_instance.web[*].private_ip)

│ The "count" value depends on resource attributes that cannot be determined
│ until apply, so OpenTofu cannot predict how many instances will be created.
│ To work around this, use the -target argument to first apply only the
│ resources that the count depends on.

The same message appears for for_each (Invalid for_each argument) whenever the key set is derived from an attribute that is unknown until apply.

What It Means

OpenTofu builds its dependency graph during plan, before anything is created. To do that it must know how many instances a resource has (count) or which keys a resource is expanded over (for_each) at plan time. If those values come from an attribute of another resource that has not been created yet — an ID, an ARN, a private IP, a generated name — OpenTofu simply does not have the number or the keys, so it cannot build a stable plan.

The rule is: the number of instances and the keys of a map must be knowable from configuration, variables, or data sources at plan time. The values inside each instance can be unknown until apply, but the shape of the resource cannot.

Common Causes

  • count = length(some_resource.foo) where some_resource is being created in the same run.
  • for_each over a map whose keys are attributes like aws_instance.web[*].id.
  • for_each over the result of a data source that itself depends on a not-yet-created resource.
  • Building a set of subnet IDs, security group IDs, or other computed attributes and feeding it to for_each.
  • A module output that is unknown at plan time being used as another module’s for_each.

Diagnostic Commands

Run a plan and read which argument OpenTofu flags:

tofu plan

Validate configuration structure first to rule out syntax issues:

tofu validate

Inspect the expression graph to see what the count/for_each depends on:

tofu graph | grep -i "count\|for_each"

Check whether the dependency already exists in state (if it does, the value is known):

tofu state list | grep aws_instance

Step-by-Step Resolution

  1. Identify the unknown value. In the example, count depends on aws_instance.web[*].private_ip, which does not exist until the instances are created.

  2. Prefer restructuring so the count/for_each is derived from configuration, not from a computed attribute. Drive both resources from the same static source:

variable "web_names" {
  type    = set(string)
  default = ["web-a", "web-b", "web-c"]
}

resource "aws_instance" "web" {
  for_each = var.web_names
  # ...
}

resource "aws_route53_record" "app" {
  for_each = var.web_names            # same static keys, known at plan
  name     = "${each.key}.example.com"
  records  = [aws_instance.web[each.key].private_ip]
}

Because both use var.web_names, the key set is known at plan time and the unknown private_ip is only used as a value.

  1. If restructuring is not immediately possible, apply the dependency first with -target, then apply everything:
tofu apply -target=aws_instance.web
tofu apply
  1. Confirm the two-stage apply completes cleanly:
Apply complete! Resources: 3 added, 0 changed, 0 destroyed.
  1. Remove the -target from your normal workflow once the resources exist; -target is a recovery tool, not a routine. On subsequent runs the attributes are known from state and the plain tofu apply works.

Prevention

  • Derive count and for_each from variables, locals built from variables, or data sources that do not depend on resources created in the same run.
  • Never key for_each on a computed attribute (IDs, ARNs, IPs). Key it on your own stable identifiers and look up the computed value inside the block.
  • Keep the shape of a resource static and let only the contents be dynamic.
  • Reserve -target for one-off bootstrapping; relying on it routinely masks a design that should be restructured.
  • When passing collections between modules, pass known keys explicitly rather than whole computed maps used for expansion.
  • Invalid for_each argument: the "for_each" set includes values derived from resource attributes that cannot be determined until apply — the for_each variant of this same problem.
  • Invalid index: The given key does not identify an element in this collection value — often follows once the shape shifts unexpectedly.
  • Error: Cycle — restructuring dependencies can introduce a graph cycle if done carelessly.
  • Saved plan is stale — can appear if you split applies and the state moves between them.

Frequently Asked Questions

Why can’t OpenTofu just figure out the count during apply? Because the dependency graph and the plan are built before apply. OpenTofu needs to know how many instances and which keys exist to produce a reviewable plan, so those must be known at plan time.

Is using -target a proper fix? It is a recovery workaround for bootstrapping, not a permanent solution. Once the depended-on resources exist, restructure so plain tofu apply works without -target.

Can I key for_each on an instance ID? No. IDs are computed at apply, so the key set is unknown at plan. Key for_each on your own static names and reference the ID as a value inside the block.

What’s the cleanest long-term pattern? Drive dependent resources from the same variable or local that produces static keys, then look up computed attributes by that key. For ready-made restructuring prompts, see the prompt library at /prompts/?stack=opentofu.

Does this differ from Terraform? No — OpenTofu inherits the same plan-time evaluation rules, so the fixes are identical. For more IaC fixes, browse the OpenTofu guides.

Free download · 368-page PDF

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?

Free download · 368-page PDF

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.