ERROR REFERENCE
CloudFormation found a circular resource dependency
The submitted template contains a dependency cycle, so CloudFormation cannot choose an order that creates or updates the named resources. This fails before provisioning and is not an IAM or retry problem.
WHAT IT MEANS
The resource graph loops back on itself
ValidationError: Circular dependency between resources: [ApiFunction, ApiPermission, Api]
CloudFormation builds edges from implicit references such as
Ref, Fn::GetAtt, and Fn::Sub, as
well as explicit DependsOn declarations. If those edges
form a loop, the change set cannot start. SAM and CDK can add edges in
the transformed or synthesized template that are not obvious in the
source file.
NEXT CHECK
Trace the cycle in the submitted template
-
Copy the logical IDs. Preserve every name listed
after
Circular dependency between resourcesand find those exact resources in the SAM-transformed or CDK-synthesized template. -
Draw both directions. Search those resources for
Ref,Fn::GetAtt,Fn::Sub, andDependsOn. Follow each edge until it returns to the starting resource; the loop is the dependency to remove. -
Break the edge, not the deployment. Remove an
unnecessary reference, pass the value through a parameter or a
separate stack, or move the dependent resource. Use
DependsOnonly for a genuine one-way ordering requirement; adding it to a cycle cannot fix the cycle. -
Validate the exact artifact:
Synthesize or transform again after the change, then retry the change set with the generated file that the deploy actually submits.sam validate --lint --template <template> cfn-lint <template>
AUTOMATE THE TRIAGE
Keep the check in your normal workflow
SAM Doctor recognizes this high-confidence CloudFormation marker and points at the dependency graph instead of sending you to IAM or leaving you with rollback noise. Runs locally; no AWS access, no log upload.
python -m pip install sam-doctor
sam-doctor diagnose deployment.log --format markdown
RELATED
Related errors
- Unresolved resource dependencies - a reference names a logical ID that does not exist.
- Malformed Fn::GetAtt parameters - the intrinsic function has the wrong shape.
- Failed to create changeset - the broad wrapper when no more specific template error is present.