Terraform: Error: Cycle (tested)

Error: Cycle means two or more resources (or data sources/modules) reference each other's attributes, so Terraform can't find a valid order to create or update them in. We built a genuine two-resource cycle on Terraform v1.16.5 and measured the exact output and fix.

1. The exact error, from a real circular reference

We defined two local_file resources whose content each read the other's content:

resource "local_file" "a" {
  filename = "${path.module}/a.txt"
  content  = local_file.b.content
}

resource "local_file" "b" {
  filename = "${path.module}/b.txt"
  content  = local_file.a.content
}

terraform plan gave, verbatim, with no other output before or after it:

Error: Cycle:
  local_file.a
  local_file.b

Why: Terraform builds a dependency graph from every reference between resources, then walks it to decide create/update order. A cycle means there's no valid starting point — a needs b's value to be known first, but b needs a's, so neither can go first. Terraform refuses rather than guess at an order.

We also tried a three-resource cycle (a → c → b → a); the error lists every node in the cycle, not just two:

Error: Cycle:
  local_file.a
  local_file.c
  local_file.b

2. terraform validate catches it too, with zero provider calls

We confirmed terraform validate reports the identical error, before any plan or provider interaction:

$ terraform validate
Error: Cycle:
  local_file.a
  local_file.b

This is because a dependency cycle is a property of the configuration's reference graph alone — Terraform can detect it from the .tf files themselves, without talking to any provider or touching real state. If you want the fastest possible check in CI, terraform validate finds this before a slower plan would.

3. The fix: break the cycle

We confirmed the fix is to remove the circular reference — have at most one side depend on the other, with the rest coming from a literal, variable, or a third resource neither one is part of:

resource "local_file" "a" {
  filename = "${path.module}/a.txt"
  content  = "hello from a"
}

resource "local_file" "b" {
  filename = "${path.module}/b.txt"
  content  = local_file.a.content
}

With the cycle broken, terraform plan ran cleanly and showed the normal Plan: 2 to add, 0 to change, 0 to destroy. summary. There's no flag or setting to allow a cycle through — it has to be removed from the configuration.

Frequently asked questions

What does Terraform's 'Error: Cycle' mean?

Two or more resources (or data sources, or modules) reference each other's attributes, so Terraform's dependency graph has no valid order to create or update them in. We reproduced it directly with two local_file resources whose content attributes each pointed at the other.

Does the error only ever show two resources?

No — it lists every resource in the cycle. We tested a three-resource cycle (a depends on c, c on b, b on a) and the error listed all three node names, not just the first two it found.

Can terraform plan or apply run anyway, ignoring the cycle?

No — we found no flag that bypasses this check. The only fix we confirmed working is removing the circular reference from the configuration itself, so at least one side no longer depends on the other.

Do I need to run plan or apply to catch a dependency cycle?

No — we measured that terraform validate reports the identical 'Error: Cycle' message, without contacting any provider or touching real state, since a cycle is detectable purely from the reference graph in your .tf files. It's the fastest check to run in CI.

Written with AI assistance. Measured on 2026-10-03 with Terraform v1.16.5 on Linux, local backend, using hashicorp/local 2.5.1 resources whose content attributes reference each other. Every message below is copy-pasted output, not paraphrased. PlainHeaders is our extension; Terraform is free.