OpenTofu Error: 'Reference to undeclared module' in Output or Expression
Fix OpenTofu's 'Reference to undeclared module' error: declare the missing module block, correct the module name, or reference an output the module actually exposes.
- #opentofu
- #terraform
- #iac
- #troubleshooting
- #errors
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: Reference to undeclared module
│
│ on outputs.tf line 3, in output "vpc_id":
│ 3: value = module.network.vpc_id
│
│ No module call named "network" is declared in the root module.
╵
The error names the module.<name> reference it could not resolve and states that no module block with that name is declared in the module you referenced it from.
What It Means
When you write module.network.vpc_id, OpenTofu expects a module "network" {} block in the same module, and it expects that module to expose a vpc_id output. Reference to undeclared module specifically means the first part failed: there is no module call with that name in this scope.
Module call names are just like resource and variable names — they live in a single module and do not cross the module boundary. An output, another module’s argument, or any expression that references module.something will fail if the module "something" {} block is missing, misnamed, or declared in a different module than the one doing the referencing.
Common Causes
- The
moduleblock was never declared, but an output or expression already references it. - A typo: the block is
module "networking"but the reference ismodule.network. - The reference lives in the root module while the
moduleblock is nested inside a child (or vice versa). - A
moduleblock was removed or renamed during a refactor and its references were left behind. - Copy-pasted output blocks from another configuration that referenced module names not present here.
Diagnostic Commands
Ask OpenTofu to pinpoint the unresolved reference:
tofu validate
List every module reference in the configuration:
grep -rn 'module\.' .
Confirm whether a matching module call exists:
grep -rn 'module "network"' .
Inspect which modules OpenTofu has actually initialized:
tofu providers
cat .terraform/modules/modules.json | tofu console
Step-by-Step Resolution
-
Run
tofu validateand read the reported file and line. Themodule.<name>in the message is the call that is missing. -
Search for a
moduleblock with that exact name in the same directory:
grep -rn 'module "network"' .
- If the module call is missing, declare it. The block name must match the reference exactly:
module "network" {
source = "./modules/network"
cidr_block = "10.0.0.0/16"
}
- If the names simply differ, fix the reference or the block so they agree:
output "vpc_id" {
value = module.network.vpc_id
}
- If you added the block, run
initso OpenTofu downloads and records the module before planning:
tofu init
- Confirm the referenced output actually exists in the child module. If
vpc_idis not declared as anoutputin./modules/network, add it there:
# modules/network/outputs.tf
output "vpc_id" {
value = aws_vpc.this.id
}
- Validate and plan:
tofu validate && tofu plan
Prevention
- Keep
moduleblocks and every reference to them in the same module; module names are not visible across the boundary. - Run
tofu initafter adding or renaming amoduleblock so OpenTofu records the call before you reference it. - Only reference outputs a child module explicitly declares with an
outputblock — referencing an internal resource directly is not allowed. - Run
tofu validatein CI so undeclared module references fail before apply. - When renaming a module, update the block and all
module.<name>references together. The prompt library has prompts that wire module outputs to root outputs consistently.
Related Errors
Reference to undeclared input variable— the same class of error for avar.reference with novariableblock.Unsupported attribute— the module is declared but the output name you referenced does not exist.Module not installed— themoduleblock exists buttofu inithas not been run.Reference to undeclared resource— aresourcereference with no matching resource block.
Frequently Asked Questions
Do I need to run tofu init after adding a module block? Yes. init downloads the module source and records it in .terraform/modules. Until then, references to it will not resolve during plan.
Why can’t the root see a module declared inside a child? Module calls are scoped to the module that declares them. If the root references module.network, the module "network" block must be in the root, not nested in a child module.
The module is declared but I still get an error on the attribute — why? That is usually Unsupported attribute, meaning the module call resolves but the specific output you referenced is not declared with an output block in the child module.
Can I reference a resource inside a module directly? No. Modules encapsulate their resources. Expose what you need through output blocks in the child and reference module.name.output_name.
Where can I find more OpenTofu troubleshooting? See the OpenTofu guides for the full library of error walkthroughs.
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?
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.