Error: Cycle
Fixes OpenTofu's 'Error: Cycle' by breaking the dependency loop, usually by splitting a self-referential security group rule into its own resource. Use when two resources or modules reference each other directly or through a chain. Not for missing references.
TL;DR: Two resources (or modules) reference each other, so tofu can't order them. Visualize with tofu graph, find the loop, and break it: replace one side with a static value, split the resource, or pass the value as a variable instead of reading it back.
Error: Cycle: module.a.aws_x.foo, module.b.aws_y.barSteps
Visualize:
tofu graph | dot -Tsvg > graph.svgand open it. Expected: you can SEE the loop instead of squinting at HCL.Identify the weakest edge: which reference can become a static value or an input variable? Expected: one reference is incidental (a tag, a name) rather than structural.
Break it. Common patterns:
- Self-referential security group: split the ingress rule into a separate
aws_security_group_ruleresource instead of inlineingressblocks. - Module A reads module B's output while B reads A's: pass the shared value in as a variable to both from the parent.
- Tag/name computed from the other resource: hardcode it or derive both from the same input.
Expected: the graph is acyclic.
- Self-referential security group: split the ingress rule into a separate
Re-run
tofu plan. Expected: the cycle error is gone.
When this applies
Error: Cycle:listing two or more addresses.- After wiring two modules/resources to each other's outputs.
When it doesn't apply
Error: Reference to undeclared resource: a dangling reference, not a loop.- Cycles through
depends_onyou added "to force ordering": remove the unnecessary edge; that's the loop.
Tool versions
All OpenTofu versions.
Why it happens
Tofu builds a dependency graph from references and walks it in topological order. A cycle means no valid order exists, so it fails fast and names the loop rather than deadlocking or guessing.
Edge cases
- Indirect cycles through three or more resources are the ones nobody spots by reading;
tofu graphis the tool, not eyeballing. depends_onedges count the same as reference edges; an unnecessarydepends_onadded "just to be safe" is a common accidental loop-closer.